Python中的对象/类属性 - 发生了什么?
有没有人能解释一下为什么Python会这样做呢?
>>> class Foo(object):
... bar = []
...
>>> a = Foo()
>>> b = Foo()
>>> a.bar.append(1)
>>> b.bar
[1]
>>> a.bar = 1
>>> a.bar
1
>>> b.bar
[1]
>>> a.bar = []
>>> a.bar
[]
>>> b.bar
[1]
>>> del a.bar
>>> a.bar
[1]
这真让人感到困惑!
6 个回答
0
当你在类里面这样声明一个元素时,这个元素会被这个类的所有实例共享。要想让每个实例都有自己独立的成员,就需要在 __init__ 方法里单独创建,像下面这样:
class Foo(object):
def __init__(self):
self.bar = []
7
这是因为你写的方式,bar
是一个类变量,而不是实例变量。
要定义一个实例变量,你需要在构造函数里绑定它:
class Foo(object):
def __init__(self):
self.bar = []
注意,现在它属于一个特定的 Foo
实例(self
),而不是 Foo
类。这样,当你给它赋值时,你会看到你期待的结果。
0
正如其他人所说,这段代码创建的是一个类变量,而不是实例变量。你需要在 __init__
方法里进行赋值,才能创建一个实例变量。
希望下面这个带注释的代码能帮助你理解每个步骤发生了什么:
>>> class Foo(object):
... bar = [] # defines a class variable on Foo (shared by all instances)
...
>>> a = Foo()
>>> b = Foo()
>>> a.bar.append(1) # appends the value 1 to the previously empty list Foo.bar
>>> b.bar # returns the value of the class variable Foo.bar
[1]
>>> a.bar = 1 # binds 1 to the instance variable a.bar, masking the access
>>> a.bar # you previously had to the class variable through a.bar
1
>>> b.bar # b doesn't have an instance variable 'bar' so this still
[1] # returns the class variable
>>> a.bar = [] # bind a's instance variable to to an empty list
>>> a.bar
[]
>>> b.bar # b doesn't have an instance variable 'bar' so this still
[1] # returns the class variable
>>> del a.bar # unbinds a's instance variable unmasking the class variable
>>> a.bar # so a.bar now returns the list with 1 in it.
[1]
另外,在每条语句执行后,打印出 Foo.bar
的值(这是通过类访问的类变量,而不是通过实例访问的)可能会帮助你更清楚地理解发生了什么。