令人费解的范围行为

时间:2012-02-22 12:07:27

标签: python scope class-members

我似乎无法理解这里发生了什么:

class testclass: 

    def __init__(self): 
        print "new instance" 
    myList=[] 

if __name__ == "__main__":  

    inst1=testclass() 
    inst1.myList.append("wrong") 

    inst2=testclass() 
    inst2.myList.append("behaviour") 

    print "I get the",inst2.myList

输出结果为:

new instance
new instance
I get the ['wrong', 'behaviour']

我原本预计 inst1 中的列表对 inst2 中的列表一无所知,但不知何故它看起来像 myList 的范围trascends类的实例化。 我发现这非常令人不安和令人费解,或者我在这里遗漏了什么?

谢谢!

6 个答案:

答案 0 :(得分:6)

您定义myList的方式是类属性。

您要查找的行为是对象属性之一:

class testclass:
    def __init__(self): 
        print "new instance"
        self.myList = []

我们试一试:

>>> t1 = testclass()
new instance
>>> t2 = testclass()
new instance
>>> t1.myList.append(1)
>>> t2.myList.append(2)
>>> t1.myList
[1]
>>> t2.myList
[2]

如果您对类属性感兴趣,请查看Class documentation。由于Python中的类也是对象,就像(几乎)Python中的所有内容一样,它们可以拥有自己的属性。

答案 1 :(得分:3)

您在类中声明myList的方式使其成为属性。如果您打算拥有实例属性,请将其声明为此类,并且它将具有预期的行为:

class testclass:
    def __init__(self): 
        print "new instance" 
        self.myList=[]

答案 2 :(得分:1)

是的,因为这是类属性的用途。如果你想要一个实例变量,你需要在实例本身声明它 - 通常在方法中使用self

答案 3 :(得分:1)

myList class 实例化时间初始化,因为它在类的主体中声明,而不是在 object 实例化时间。

然后,这些属性与实例共享,直到在实例上创建具有相同名称的变量。

因此,在您的情况下,您正在使用每个对象访问相同的myList对象(并为其附加值)。

答案 4 :(得分:0)

class testclass:

    def __init__(self):
        self.myList=[]
        print "new instance"

答案 5 :(得分:0)

如果希望myList是实例变量,则应在init函数中定义self.myList。然后你应该得到你期望的行为。正如你现在所知,我认为myList是一个类变量,并且将由该类的所有实例共享。