[英]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)
). (请注意,您还需要为Class1
和Class2
创建__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.