Python:派生类访问位于同一内存位置的基类的字典



我想知道为什么在基类中定义并从派生类访问的字典显然只存在于一个内存位置。一个简短的例子:

class BaseClass:
    _testdict = dict()
    _testint = 0
    def add_dict_entry(self):
        self._testdict["first"] = 1
    def increment(self):
        self._testint += 1
class Class1(BaseClass):
    pass
class Class2(BaseClass):
    pass
object1 = Class1()
object2 = Class2()
object1.add_dict_entry()
object1.increment()
print(object2._testdict)
print(object2._testint)

输出为:

{'first': 1}
0

为什么对对象1的"add_dict_entry"的调用会影响对象2的字典?使用整数("increment"),基类变量不受影响。

非常感谢。

Lorenz

这是因为_testdict是一个类变量:在最初构造类时,它只定义一次。如果您希望它对每个实例都是独立的,请将其作为实例变量:

class BaseClass:
    _testint = 0
    def __init__(self):
        self._testdict = dict()
    def add_dict_entry(self):
        self._testdict["first"] = 1

(请注意,您还需要为Class1Class2创建__init__方法,这两个方法都必须调用BaseClass.__init__(self))。

_testint的行为不同,因为您对它执行的是重新绑定操作,而不是变异操作。int是不可变的,所以不能"更改"一个——self._testint += 1只是self._testint = self._testint + 1的语法糖。类似地,您可以对实例之间不共享的self._testdict执行重新绑定操作——例如,self._testdict = {}将仅重置该实例的_testdict

在python中,int是不可变的,因此+=操作将类变量反弹到实例变量中。另一方面,字典索引会使字典在适当的位置发生变化。一个更类似的例子是

def add_dict_entry(self):
    # create a new dict
    tmp = dict(self._testdict)
    tmp["first"] = 1
    # shadow the class variable with an instance variables
    self._testdict = tmp

最新更新