Python:类中的静态对象

Python:类中的静态对象,python,class,dictionary,static,Python,Class,Dictionary,Static,我想知道如何在python类中正确地保留静态对象。 在这种情况下,我想要一个静态字典 >>> dTest.d = {} >>> a.d {} >>> a.d = {"Fourth":4} >>> a.d {'Fourth': 4} >>> dTest.d {} 这只是我想要的一个简单例子: class dTest: # item I want to be static d = {"Fir

我想知道如何在python类中正确地保留静态对象。 在这种情况下,我想要一个静态字典

>>> dTest.d = {}
>>> a.d
{}
>>> a.d = {"Fourth":4}
>>> a.d
{'Fourth': 4}
>>> dTest.d
{}
这只是我想要的一个简单例子:

class dTest:
    # item I want to be static
    d = {"First":1}

>>> a = dTest()
>>> a.d
{'First': 1}
>>> dTest.d["Second"] = 2
>>> a.d["Third"] = 3
>>> a.d
{'Second': 2, 'Third': 3, 'First': 1}
>>> dTest.d
{'Second': 2, 'Third': 3, 'First': 1}
现在,如果我直接调用该类并用新字典替换d

>>> dTest.d = {}
>>> a.d
{}
>>> a.d = {"Fourth":4}
>>> a.d
{'Fourth': 4}
>>> dTest.d
{}
但是,如果我用一本新字典替换a.d,我也希望有相同的功能

>>> dTest.d = {}
>>> a.d
{}
>>> a.d = {"Fourth":4}
>>> a.d
{'Fourth': 4}
>>> dTest.d
{}
我现在想要的结果是dTest.d与a.d相同(dTest.d是{'Fourth':4})

是否有适当的做法,或者我必须确保只有在从dTest实例编辑对象时才编辑对象


谢谢

处理类时有两种不同类型的变量:实例变量和类变量

可以从类的所有实例以及类本身访问类变量:

>>> class Foo(object):
...    class_var = {'one': 1}
...
>>> Foo.class_var
{'one': 1}
>>> a, b = Foo(), Foo()
>>> a.class_var
{'one': 1}
>>> b.class_var
{'one': 1}
>>> a.class_var is b.class_var 
True # These are the same object
>>> 
实例变量只能从指定给它们的特定实例访问:

>>> class Foo(object):
...     def __init__(self):
...             self.instance_var1 = {'two': 2}
... 
>>> foo = Foo()
>>> foo.instance_var2 = {'three': 3}
>>> foo.instance_var1
{'two': 2}
>>> foo.instance_var2
{'three': 3}
>>> Foo.instance_var1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute 'instance_var1'
具体回答你的问题。如果要更改类变量,必须从类而不是实例进行设置,因此:

dTest.d = {'blah': 'blah'}

如果你这么做的话

a.d = {'blah': 'blah'}

您创建了一个
a
的实例变量,该实例变量会隐藏或覆盖同名的类变量。

当您向
d
添加键值对时,可以使用
a.d[key]=…
dTest.d[key]=…
将共享您在类中使用的词典,您没有更改
d
的引用,因此它仍然是一个共享类属性

但是,如果您尝试将某个属性分配给
a.d
,如
a.d=123
a.d=[11,22]
,则会创建一个属性
d
,例如
a
,而
a.d
不再引用
dType.d
。见:

注意:如果对象是类实例,并且属性引用发生在赋值运算符的两侧,则RHS表达式,
a.x
可以访问实例属性或(如果不存在实例属性)类属性。LHS目标
a.x
始终设置为实例属性,必要时创建它。因此,a.x的两个引用不一定引用相同的属性:如果RHS表达式引用类属性,则LHS将创建一个新实例属性作为赋值的目标:


使用
property
创建getter和setter在更改
a.d
后尝试更改
dTest.d
,您会注意到
a.d
将不再随
dTest.d
而更改@JBernardo:通过类访问
d
时,属性将不起作用…@brunodesthuilliers如果创建它,它将不会起作用在一个元类下。@JBernardo是的,确实这是一个可能的解决方案-即使可能有点过分,谢谢你的快速回复!这很有道理!