Python类中的属性是否共享?

Yic*_*hen 10 python class list

以下代码困扰我: -

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
Run Code Online (Sandbox Code Playgroud)

输出是: -

hello world bye world
['hello world', 'bye world'] ['hello world', 'bye world']
Run Code Online (Sandbox Code Playgroud)

这意味着列表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
Run Code Online (Sandbox Code Playgroud)

输出如下: -

a list
hello world bye world
['hello world', 'hello world'] ['bye world', 'bye world']
Run Code Online (Sandbox Code Playgroud)

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

小智 9

不同之处在于,在第二个示例中,您将创建一个新列表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)
Run Code Online (Sandbox Code Playgroud)

第一个例子是因为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)
Run Code Online (Sandbox Code Playgroud)

这将输出你实际期望的东西.