This question already has answers here:
python class instance variables and class variables

(4个答案)



How to avoid having class data shared among instances?

(7个答案)


3年前关闭。




下面的代码困扰我:
class mytest:
    name="test1"
    tricks=list()
    def __init__(self,name):
        self.name=name
        #self.tricks=[name]
        self.tricks.append(name)

t1=mytest("hello world")
t2=mytest("bye world")
print t1.name,t2.name
print t1.tricks,t2.tricks

输出为:-
hello world bye world
['hello world', 'bye world'] ['hello world', 'bye world']

这意味着列表tricks由两个实例t1和t2共享,这在https://docs.python.org/3/tutorial/classes.html的9.3.5节中已经进行了解释

但是,如果我执行以下代码:
class mytest:
    name="test1"
    tricks=list()
    def __init__(self,name):
        self.name=name
        self.tricks=[name]
        self.tricks.append(name)

t1=mytest("hello world")
t2=mytest("bye world")
x=t1.tricks
if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'
print t1.name,t2.name
print t1.tricks,t2.tricks

输出如下:
a list
hello world bye world
['hello world', 'hello world'] ['bye world', 'bye world']

现在,列表tricks似乎不再被这两个实例t1和t2共享。
我的问题是,这里的机制是什么?

最佳答案

不同之处在于,在第二个示例中,您正在创建一个新列表self.tricks作为对象的属性:

def __init__(self,name):
    self.name=name
    self.tricks=[name]    # <-- this is creating the new attribute for the object
    self.tricks.append(name)

第一个示例之所以有效,是因为Python解析名称的方式:如果在对象中找不到self.tricks(因为尚未创建),那么它将尝试将其作为类的成员来查找。由于有技巧,因此您可以访问它。

如果您在第二个示例中尝试使用mytest.tricks,则可能对您很清楚:
def __init__(self,name):
    self.name=name
    mytest.tricks=[name]    # <-- this is accesing the class attribute instead
    self.tricks.append(name)

这将输出您的实际期望。

09-25 21:20