为什么在python中共享列表而不是变量(类级别)

时间:2014-04-17 15:31:13

标签: python oop

class abc :
    x = 10
    list = []   
    def __init__(self):
        self.a = 30      
        self.b = 40

a = abc()
b = abc()
a.x = a.x + 1
print a.x
print b.x
a.list.append(1)
print b.list   

Output :
10
11
[1]

因此,我们发现x未在对象ab之间共享,但list已共享。有人可以解释这种行为吗?

所以它的答案似乎在于列表是可变的objs而数字不是:

class abc :
   x = 10
   m_list = []

   def __init__(self):
       self.a = 30      
       self.b = 40



a = abc()
b = abc()
print id(a.x)
a.x = a.x + 1
print id(a.x)
print a.x
print b.x
print id(a.m_list)
a.m_list.append(1)
print id(a.m_list)
print b.m_list
print id(b.m_list)


output :
5342052
5342040
11
10
38600656
38600656
[1]
38600656

but this is so strange ...numbers are immutable ?

3 个答案:

答案 0 :(得分:6)

它们在所有类的实例中共享,但区别在于列表是 mutable ,但整数是不可变的

此:

a.x = a.x + 1

创建一个新的不可变int对象*,然后将a.x(但 b.x)指向新对象。

相比之下,这个:

a.list.append(1)

修改了可变list个对象a.list(和b.list)已经指向就地。

您可以使用例如

更一致地修改不可变类属性
abc.x = abc.x + 1
abc.list.append(1)

并且不要调用自己的变量list

*小整数是"实习"在CPython中,但现在不要担心

答案 1 :(得分:2)

列表是一个可变数据结构,因为你在类级别创建它,它与其他语言中的静态变量相似...但是,因为当你改变a.x时整数是不可变的,你实际上是在创建一个新的a.x值并且不会影响b.x

class abc :
    x = 10  
    def __init__(self):
        self.a = 30      
        self.my_list = [] #now its tied to the instance rather than the class
        self.b = 40

你实际上可以看到a.x在递增后不是同一个对象

>>> id(a.x)
5321432
>>> a.x += 1
>>> id(a.x)
5321420  #notice the address of the object is different

答案 2 :(得分:-1)

它与列表无关,但事实上,在您的示例中,a.x已更新并创建了一个实例级变量,该变量不再在实例之间共享。

但是如果你更新它,同样的事情发生在列表中。为了证明我的断言,我将使用返回对象唯一ID的id()原语:

class abc :
    x = 10
    my_list = []

    def __init__(self):
        self.a = 30
        self.b = 40

a = abc()
b = abc()
print "id(a.x) = %d" % id(a.x) # identifier of a.x
print "id(b.x) = %d" % id(b.x) # identifier of b.x = a.x
a.x = a.x + 1
print "id(a.x) = %d" % id(a.x) # changed
print "id(b.x) = %d" % id(b.x) # unchanged
print a.x
print b.x
a.my_list.append(1)
print b.my_list
print "id(a.mylist) = %d" % id(a.my_list)
print "id(b.mylist) = %d" % id(b.my_list) 

a.my_list = [42]
print "id(a.mylist) = %d" % id(a.my_list) # changed
print "id(b.mylist) = %d" % id(b.my_list)

给出了:

id(a.x) = 154513476
id(b.x) = 154513476
id(a.x) = 154513464  # changed
id(b.x) = 154513476
11
10
[1]
id(a.mylist) = 3072656236
id(b.mylist) = 3072656236
3072781100
3072656236
id(a.mylist) = 3072781100  # changed
id(b.mylist) = 3072656236

顺便说一下,我已经重命名了list变量。请不要使用保留字作为变量名。