简体   繁体   English

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

[英]Python: derived classes access dictionary of base class in the same memory location

I'm wondering why a dictionary, that is defined in a base class and is accessed from derived classes, is obviously present only in one memory location. 我想知道为什么在基类中定义并从派生类访问的字典显然只存在于一个内存位置。 A short example: 一个简短的例子:

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)

and the output is: 输出是:

{'first': 1}
0

Why does a call to the "add_dict_entry" of object1 affect the dictionary of object2? 为什么对object1的“add_dict_entry”的调用会影响object2的字典? Using integers ("increment") the base class variable is not affected. 使用整数(“增量”),基类变量不受影响。

Thanks a lot. 非常感谢。

Lorenz 洛伦茨

It's because _testdict is a class variable: it's defined only once, when the class is initially constructed. 这是因为_testdict是一个类变量:当最初构造类时,它只定义一次。 If you want it to be separate for each instance, make it an instance variable: 如果您希望它对每个实例分开,请将其设为实例变量:

class BaseClass:
    _testint = 0

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

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

(Note that you'd need to create __init__ methods for Class1 and Class2 as well, both of which would have to call BaseClass.__init__(self) ). (请注意,您还需要为Class1Class2创建__init__方法,这两种方法都必须调用BaseClass.__init__(self) )。

_testint behaves differently because you're performing a rebinding operation on it rather than a mutating operation. _testint行为有所不同,因为您正在对其执行重新绑定操作而不是变异操作。 ints are immutable, so you can't "change" one- self._testint += 1 is just syntactic sugar for self._testint = self._testint + 1 . int是不可变的,所以你不能“改变”one- self._testint += 1只是self._testint = self._testint + 1语法糖。 Similarly, you can perform a rebinding operation on self._testdict that won't be shared between instances- for example, self._testdict = {} will reset only that instance's _testdict . 类似地,您可以对self._testdict执行不会在实例之间共享的重新绑定操作 - 例如, self._testdict = {}重置该实例的_testdict

In python, int is immutable, therefore the += operation will rebound the class variable into an instance variables. 在python中,int是不可变的,因此+ =操作会将类变量重新转换为实例变量。 On the other hand, a dictionary indexing mutates the dictionary in place. 另一方面,字典索引会将字典变异。 A more comparable example would be 一个更具可比性的例子

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM