Python中的对象变量有多少个内存副本?

JoJ*_*oJo 8 python java

我最近是python的新手.以前我的所有编程知识都限于Java.所以我在这里有一个关于Python中对象变量的问题.我知道Python中的对象变量在类实例上共享.例如.

class A:
    list=[]

y=A()
x=A()

x.list.append(1)
y.list.append(2)
x.list.append(3)
y.list.append(4)

print x.list
    [1,2,3,4]
print y.list
    [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

所以我的问题是有多少内存副本A.list?只有1或只有实例数?python共享行为中的对象变量就像Java的静态类变量一样,这两个概念是相同还是不同?如果不同,他们之间有什么区别?

mgi*_*son 3

在 python 中,在类作用域中声明的任何内容实际上都是全局的。当您在实例上查找该属性时,python 找不到它,因此它会查找该类(然后它继续按照方法解析顺序一直查找基类)。因此,在您的情况下,x.list与 完全相同,A.list因为没有附加listx. 类似地,与soy.list相同并且引用相同的底层列表。(唷!)A.listx.listy.list

据我了解,这至少与Java的静态相似(尽管我对Java不够流利,无法准确地说出有多相似)。

解除属性与类的关联的典型方法是将该属性绑定到实例(通常在 中__init__):

class A(object):
    def __init__(self):
        self.list = []
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,self是实例,它被(隐式)传递给任何“正常”方法(包括“魔术”方法,例如__init__)。

现在,如果您再次进行实验,您会发现 的x.list值是[1, 3]y.list现在是[2, 4]


现在测试。如果你在这门课上做实验会发生什么?

class A(object):
    list = []
    def __init__(self):
        self.list = []
Run Code Online (Sandbox Code Playgroud)

答案:x.list = [1, 3]y.list = [2, 4]。原因是因为当 python 这样做时,它首先x.list查看实例(在查看类之前)。由于在实例上找到了具有该名称的属性,因此将使用该属性。list