Python:动态类生成:覆盖成员

标签 python inheritance name-mangling dynamic-class-creation

我有一个 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!?

突然 DC 的子类,在 'dict' 中的值与其父类(super class)相同!?

哪位好心人给我解释一下,这是什么原因?提前致谢!

最佳答案

phild,如您所知,当您在属性名称前加上双下划线 __ 时,python 解释器会自动将属性名称从 __attribute 更改(mangles)为 _CLS__attribute,其中 CLS 是类名。

但是,当你说

返回类型(名称,(cls,),{'__dict':{}})

字典 { '__dict' : {} } 中的键不会被破坏。 __dict 保持不变。

因此 D 以 D._C__dictD.__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/

相关文章:

python - 如何在 Pandas 中格式化日期列?

python - 标准库中有Python inspect.getcallargs 的逆操作吗?

python - 继承中命名空间的顺序是什么?

java - 在父类(super class)/子类框架中使用 ArrayLists

c++ - 子类会影响虚拟方法的可见性吗?

c++ - extern const 链接规范似乎被 G++ 忽略

C++ 获取函数/方法的错位名称

python - 模块未找到错误 : No module named 'google.cloud'

python - 在二维矩阵中找出相同颜色的 block

inheritance - 有没有办法使用 MySQL Workbench 对表继承进行建模?