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

时间:2012-08-24 14:55:29

标签: python inheritance dictionary

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

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

为什么对object1的“add_dict_entry”的调用会影响object2的字典?使用整数(“增量”),基类变量不受影响。

非常感谢。

洛伦茨

2 个答案:

答案 0 :(得分:10)

这是因为_testdict是一个类变量:它在最初构造类时只定义了一次。如果您希望它为每个实例分开,请将其设为实例变量:

class BaseClass:
    _testint = 0

    def __init__(self):
        self._testdict = dict()

    def add_dict_entry(self):
        self._testdict["first"] = 1

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

_testint表现不同,因为您正在对其执行重新绑定操作而不是变异操作。 int是不可变的,所以你不能“改变”one self._testint += 1只是self._testint = self._testint + 1的语法糖。同样,您可以在self._testdict上执行不会在实例之间共享的重新绑定操作 - 例如,self._testdict = {}将仅重置 该实例的_testdict。< / p>

答案 1 :(得分:2)

在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