覆盖整个对象

时间:2011-03-25 21:35:15

标签: python

x = something_mutable
y = x
z = x

# sometime later make z reference something else, e.g. a list
my_list = [1, 2, 3]

# how to make x, y, z to reference my_list without using x and y explicitly
???

有可能吗?不是真的会用它,但很好奇。

相关问题。如何擦除整个列表/字典内容并复制另一个列表/字典的整个内容。我知道该怎么做,但好奇大师会怎么做。 Python很大,我刚刚开始学习它(努力不在Python中编写C代码:))。

感谢。

3 个答案:

答案 0 :(得分:5)

在回答第一个问题时:你不能这样做,如果可以,你就不应该这样做。

回答第二个问题:列表a[:]=b。对于词典,a.clear(); a.update(b)

答案 1 :(得分:1)

要记住的关于Python的事情是你有对象,它们是某个地方“在那里”的数据块;并且您有名称引用其中一些对象。并非所有对象都有直接引用它们的名称;例如,如果您的列表中包含其他列表,字符串,数字等,通常只有最外面的列表会有一个引用它的名称;通过对列表进行操作来访问所有包含的对象。

理解这一点非常重要,因为它可以澄清当你做事时幕后发生的事情。如果您del x,则不会删除对象x所指的;它只删除名称x。如果y仍引用该对象,则不会更改。我认为没有办法直接删除对象;如果删除对它的所有引用并让垃圾收集器处理它,你可以做的所有事情。

同样,如果x指的是某些东西,那么你重新分配它,你只是告诉解释者,“好的,现在我想要x来引用另一个对象。”用于引用的对象x不受影响(除了可能是垃圾回收)。

考虑这个例子:

def f(x, foo=[]):
    foo.append(x)
    return foo

这会返回每次调用f()时都会增长的列表。另一方面:

def f(x, foo=[]):
    foo = foo + [x]
    return foo

这不能按预期工作。 foo用于引用在定义或首次调用f()时创建的列表(我不记得)。然后我们获取该列表,向其添加另一个列表以创建一个全新的列表,将新列表分配给名称foo,然后将其返回。下次我们致电f()时,foo将被重新分配到旧的空列表,我们上次没有更改。

答案 2 :(得分:1)

Python的常规流程的设计方式不允许在不创建特殊对象的情况下执行所需操作。

但Python足够强大,允许创建这样的对象作为特殊类的实例,其行为将是所需的。

以下代码中有一些复杂的点,但是A类的实例以给出它们想要的行为的方式链接,并且我认为没有其他方法可以更简单地为它们提供这种集体行为。

class A(dict):

    li = []

    def __init__(self,k = None,x = None):
        weeth = ' empty'
        if (k,x)!=(None,None) and type(x)==type(1):
            weeth = ' with value '+repr(x+5)+' for key '+repr(k)
            super(A, self).__setitem__(k,x+5)
        A.li.append(self)
        print '\n  Instanciation of '+str(id(self))+weeth


    def __setitem__(self,k,val):
        if type(val)==type(1):
            super(A, self).__setitem__(k,val+2)
            print '\n  Assignement of '+repr(val+2)+' to '+str(id(self))
            also = [id(el) for el in A.li if el!=self]
            for el in A.li:
                if el!=self:
                    el.clear()
                    super(A, el).update(self)
                    el = self.items()
            if also: print '  assignement done also for each of '+repr(also)
        else:
            print '\n  Assignement of a non-integer '+repr(val)+' to '+str(id(self))+' : IMPOSSIBLE'




a = A('bn',12)
print 'A.li==',A.li
print 'a==',a

a[0] = 10
print 'a==',a

b =A()
print 'A.li==',A.li
print 'b==',b

c =A()
print 'A.li==',A.li
print 'c==',c
c['IMP'] = 'Elizabeth Taylor'
print 'c==',c

d =A('ZUI',103)
print 'A.li==',A.li
print 'd==',d

print '\na==',a
print 'b==',b
print 'c==',c
print 'd==',d


c['X45'] = 22
print 'a==',a
print 'b==',b
print 'c==',c
print 'd==',d

print '\n=========================================='

A.li = []

print "\nCreation of {'maize': 3, 'rice': 12, 'wheat': 7} with name 'x'"
x = A()
x['rice'] = 10
x['wheat'] = 5
x['maize'] = 1

print "\nCreation of {'yval':50} with name 'y' and {} with name 'z'"
y = A('yval',45)
z = A()

print '\nx==',x
print 'y==',y
print 'z==',z
print

def assign(d,dic):
    d.update(dic)
    k = d.iterkeys().next()
    d[k] = d[k]

assign(z, {'kilo':123,'jili':14,'somoto':78})
print 'x==',x
print 'y==',y
print 'z==',z

结果

  Instanciation of 18527472 with value 17 for key 'bn'
A.li== [{'bn': 17}]
a== {'bn': 17}

  Assignement of 12 to 18527472
a== {0: 12, 'bn': 17}

  Instanciation of 18528232 empty
A.li== [{0: 12, 'bn': 17}, {}]
b== {}

  Instanciation of 18528080 empty
A.li== [{0: 12, 'bn': 17}, {}, {}]
c== {}

  Assignement of a non-integer 'Elizabeth Taylor' to 18528080 : IMPOSSIBLE
c== {}

  Instanciation of 18528384 with value 108 for key 'ZUI'
A.li== [{0: 12, 'bn': 17}, {}, {}, {'ZUI': 108}]
d== {'ZUI': 108}

a== {0: 12, 'bn': 17}
b== {}
c== {}
d== {'ZUI': 108}

  Assignement of 24 to 18528080
  assignement done also for each of [18527472, 18528232, 18528384]
a== {'X45': 24}
b== {'X45': 24}
c== {'X45': 24}
d== {'X45': 24}

==========================================

Creation of {'maize': 3, 'rice': 12, 'wheat': 7} with name 'x'

  Instanciation of 18528536 empty

  Assignement of 12 to 18528536

  Assignement of 7 to 18528536

  Assignement of 3 to 18528536

Creation of {'yval':50} with name 'y' and {} with name 'z'

  Instanciation of 18528688 with value 50 for key 'yval'

  Instanciation of 18528840 empty

x== {'maize': 3, 'rice': 12, 'wheat': 7}
y== {'yval': 50}
z== {}


  Assignement of 125 to 18528840
  assignement done also for each of [18528536, 18528688]
x== {'somoto': 78, 'jili': 14, 'kilo': 125}
y== {'somoto': 78, 'jili': 14, 'kilo': 125}
z== {'kilo': 125, 'jili': 14, 'somoto': 78}