5

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

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的字典?使用整数(“增量”),基类变量不受影响。

非常感谢。

洛伦兹

4

2 回答 2

10

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

class BaseClass:
    _testint = 0

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

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

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

_testint行为不同,因为您正在对其执行重新绑定操作而不是变异操作。ints 是不可变的,所以你不能“改变” one-self._testint += 1只是self._testint = self._testint + 1. self._testdict同样,您可以对不会在实例之间共享的对象执行重新绑定操作,例如,self._testdict = {}重置该实例的_testdict.

于 2012-08-24T14:57:07.837 回答
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
于 2012-08-24T15:04:44.267 回答