我想知道如何在python类中正确保存静态对象。 在这种情况下,我想要一个静态字典
只是我正在寻找的一个简单例子:
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,我也想拥有相同的功能
>>> a.d = {"Fourth":4}
>>> a.d
{'Fourth': 4}
>>> dTest.d
{}
我现在想要的结果是dTest.d与a.d相同(dTest.d为{'Fourth':4})。
是否有适当的练习,或者我是否必须确保只在dTest实例中编辑对象?
谢谢!
答案 0 :(得分:4)
处理类时有两种不同类型的变量:实例变量和类变量。
类变量可以从类的所有实例以及类本身访问:
>>> 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'
实例变量可以覆盖类变量:
>>> class Foo(object):
... my_var = {'one': 1} # This a class variable
...
>>> foo = Foo()
>>> foo.my_var = {'two': 2} # Override class my_var with instance my_var
>>> foo.my_var
{'two': 2}
>>> Foo.my_var
{'one': 1}
>>> foo.__class__.my_var # But you can still access the class variable like this.
{'one': 1}
>>>
专门回答你的问题。如果要更改类变量,则必须从类而不是实例设置它,因此:
dTest.d = {'blah': 'blah'}
或
a.__class__.d = {'blah': 'blah'}
如果你这样做
a.d = {'blah': 'blah'}
您创建一个a
的实例变量,该变量可以隐藏或覆盖具有相同名称的类变量。
答案 1 :(得分:0)
您在班级中使用的词典是共享的,当您使用d
或a.d[key]=...
将键值对添加到dTest.d[key]=...
时,您不会更改d
,所以它仍然是一个共享的类属性。
但是,如果您尝试将某些内容分配给a.d
,例如a.d=123
或a.d=[11,22]
,则为实例d
创建属性a
,并{{ 1}}不再引用a.d
。见Assignment statements:
注意:如果对象是类实例并且赋值运算符的两侧都出现属性引用,则RHS表达式dType.d
可以访问实例属性或(如果不存在实例属性) )一个类属性。 LHS目标a.x
始终设置为实例属性,必要时创建它。因此,两次出现的a.x不一定引用相同的属性:如果RHS表达式引用了一个类属性,LHS会创建一个新的实例属性作为赋值的目标:
a.x