python - 类属性显然不是继承的

thr*_*ein 9 python metaclass class-attributes

在最近的一个项目中,我尝试做这样的事情(更复杂,但结果相同):

class MetaA(type):
    def __new__(cls, name, args, kwargs):
        print kwargs["foo"]
        return type.__new__(cls, name, args, kwargs)

class A(object):
    __metaclass__ = MetaA
    foo = "bar"

class B(A):
    pass
Run Code Online (Sandbox Code Playgroud)

我明白了:

bar
Traceback (most recent call last):
  File "C:\Users\Thorstein\Desktop\test.py", line 10, in <module>
    class B(A):
  File "C:\Users\Thorstein\Desktop\test.py", line 3, in __new__
    print kwargs["foo"]
KeyError: 'foo'
Run Code Online (Sandbox Code Playgroud)

类属性是否未继承?如果是这样,在与上述类似的框架中是否有可能的解决方法?

编辑:可能更容易看到我的意思使用程序中的实际(简化)示例..

class GameObjectMeta(type):
    def __new__(cls, name, bases, attrs):
        attrs["dark_color"] = darken(*attrs["color"])
        return type.__new__(cls, name, bases, attrs)


class GameObject(object):
    __metaclass__ = GameObjectMeta
    color = (255,255,255)   # RGB tuple

class Monster(GameObject):
    pass
Run Code Online (Sandbox Code Playgroud)

基本上,想要在基色上运行一个函数来制作一个保存在类中的较暗的函数(类的多个实例将需要相同的颜色,但是将有更长的类层次结构).我希望这会更有意义..

Bre*_*arn 4

它不应该继承这些。元类接收在其实例化的类上定义的属性,而不是其基类的属性。元类构造函数的全部目的是访问类主体中实际给出的内容。

事实上,基类的属性实际上根本不在子类“中”。当您定义子类时,它们并不是被“复制”到子类中,事实上,在创建时子类甚至不“知道”其超类可能具有哪些属性。相反,当您访问 B.foo时,Python 首先尝试在 B 上查找该属性,然后如果找不到,则查找其超类。每次您尝试读取此类属性时,都会动态发生这种情况。元类机制不应该访问超类的属性,因为这些属性实际上不存在于子类中。

一个可能相关的问题是您的定义__new__不正确。元类的参数__new__是 cls、name、bases 和 attrs。第三个参数是基类列表,而不是“args”(无论您想要什么)。第四个参数是类主体中定义的属性列表。如果您想访问继承的属性,您可以通过基础来获取它们。

不管怎样,你想通过这个计划实现什么目的?可能有更好的方法来做到这一点。