与python类声明的变量有些混淆

some confusion with variables declared by python class

我上课了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> class Foo:
...     ls=[]
...
>>> f1=Foo()
>>> f2=Foo()
>>> f1.ls.append(1)
>>> f1.ls.append(2)
>>> print f1.ls
[1, 2]
>>> print f2.ls  
[1, 2]                #I expect its result is empty [], why
>>> f2.ls=[]
>>> print f1.ls      
[1, 2]
>>> print f2.ls
[]
           # If f1.ls and f2.ls refer to the same list, since i modify f2.ls,
           # the f1.ls is empty ,too. Does the statement 'f2.ls=[]' add new attribute
           # to f2. Where do f1.ls and f2.ls refer and how it happens

我想使用一个类并声明许多变量。如果我希望所有变量都有不同的列表。我喜欢这个吗

1
2
3
4
5
6
7
class Foo:
    pass
f1=Foo()
f2=oo()
f1.ls=[]
f2.ls=[]
do others

有更简单更好的方法吗?请原谅我对python类的无知。提前谢谢


类级分配创建类变量。要创建实例变量,请在构造函数中执行此操作:

1
2
def __init__(self):
    self.ls = []

当你说

1
2
class Foo:
    ls=[]

ls被定义为类变量,您创建的所有对象都将有一个同名的变量,该变量将指向类的ls值中的当前值。

当你说

1
f1.ls.append(1)

实际上您正在改变原始对象。这就是为什么变化也反映在f2中(因为它们都指同一个对象)。但当你说

1
f2.ls = []

实际上,您正在f2对象上创建一个变量,该对象引用一个空列表对象。现在,ls对象不同于f1的ls。你可以用这句话来证实这一点

1
2
print f1.ls is f2.ls    # Will print False
print f1.ls is Foo.ls   # Will print True

如果你真的想在你创建一个对象的时候得到一个新的对象。您必须创建一个实例变量,如下所示

1
2
3
4
5
6
class Foo:
    def __init__(self):
        self.ls = []

f1, f2 = Foo(), Foo()
print f1.ls is f2.ls    # Will print False

现在您将ls绑定到类的当前实例,并使其指向一个空列表。所以,对于每个实例,这都是不同的。


直接在类内定义一个变量会给出一个类级变量。因此,ls不是所有实例的唯一性,而是类Foo的一个属性。但是,它仍然可以通过实例访问,这就是您所做的。

1
2
class Foo:
    ls = []

以便:

1
2
3
4
5
6
7
8
9
>>> f1 = Foo()
>>> f2 = Foo()
>>> Foo.ls.append(1)
>>> Foo.ls
[1]
>>> f1.ls
[1]
>>> f2.ls
[1]

实例级变量对每个实例都是唯一的,可以在__init__函数中定义,例如:

1
2
3
class Foo:
    def __init__(self):
        self.ls = []

这样,类foo就没有属性ls;相反,用__init__构造的每个实例都有:

1
2
3
4
5
6
7
8
9
10
11
>>> f1 = Foo()
>>> f2 = Foo()
>>> Foo.ls.append(1)
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
AttributeError: class Foo has no attribute 'ls'
>>> f1.ls.append(1)
>>> f1.ls
[1]
>>> f2.ls
[]


ls是您定义的静态变量。你自己在初始化中,所以你可以在内存中有不同的ls。