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

2024-05-19 01:38:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我上课了

>>> 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

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

class Foo:
    pass
f1=Foo()
f2=oo()
f1.ls=[]
f2.ls=[]
do others

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


Tags: andthetofooisdolsclass
3条回答

当你说

class Foo:
    ls=[]

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

当你说

f1.ls.append(1)

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

f2.ls = []

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

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

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

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

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

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

直接在类中定义变量会产生类级变量。因此,ls并非对所有实例都是唯一的,而是类Foo的属性。但是,仍然可以通过它的实例访问它,这就是您所做的。你知道吗

class Foo:
    ls = []

以便:

>>> f1 = Foo()
>>> f2 = Foo()
>>> Foo.ls.append(1)
>>> Foo.ls
[1]
>>> f1.ls
[1]
>>> f2.ls
[1]

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

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

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

>>> 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
[]

类级赋值创建类变量。要创建实例变量,请在构造函数中执行以下操作:

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

相关问题 更多 >

    热门问题