我有一个 python 类层次结构,我想在运行时对其进行扩展。此外,此层次结构中的每个类都有一个静态属性“dict”,我想在每个子类中覆盖它。简单化它看起来像这样:
'dict' 是一个 protected (公共(public)但带有前导下划线)成员
class A(object):
_dict = {}
@classmethod
def getdict(cls):
return cls._dict
@classmethod
def setval(cls, name, val):
cls._dict[name] = val
@classmethod
def addchild(cls, name):
return type(name, (cls, ), { '_dict' : {} })
B = A.addchild('B')
A.setval(1, 5)
print A.getdict()
# prints: {1: 5}
# like expected
print B.getdict()
# prints: {}
# like expected
这就像预期的那样工作。现在的问题是:如果我将属性声明为私有(private),为什么它不再起作用:
现在“dict”成为私有(private)成员也是一样
class C(object):
__dict = {}
@classmethod
def getdict(cls):
return cls.__dict
@classmethod
def setval(cls, name, val):
cls.__dict[name] = val
@classmethod
def addchild(cls, name):
return type(name, (cls, ), { '__dict' : {} })
D = C.addchild('D')
C.setval(1, 5)
print C.getdict()
# prints: {1: 5}
# like expected
print D.getdict()
# prints: {1: 5}
# why!?
突然 D
,C
的子类,在 'dict' 中的值与其父类(super class)相同!?
哪位好心人给我解释一下,这是什么原因?提前致谢!
最佳答案
phild,如您所知,当您在属性名称前加上双下划线 __
时,python 解释器会自动将属性名称从 __attribute
更改(mangles)为 _CLS__attribute
,其中 CLS 是类名。
但是,当你说
返回类型(名称,(cls,),{'__dict':{}})
字典 { '__dict' : {} }
中的键不会被破坏。 __dict
保持不变。
因此 D 以 D._C__dict
和 D.__dict
结束:
(Pdb) dir(D)
['_C__dict', '__class__', '__delattr__', '__dict', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'addchild', 'getdict', 'setval']
D._C__dict
指的是C的类属性。所以当你运行时
C.setval(1, 5)
您正在更改 D._C__dict
以及 C._C__dict
。它们是一回事。
关于Python:动态类生成:覆盖成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1792104/