【发布时间】:2019-05-02 21:51:19
【问题描述】:
我有课;我们称之为Foo。它有一个key_type 类属性,其中包含一个类型:
class Key: pass
class Foo:
key_type = Key
我想在键类型被初始化(*)时以及它发生变化时对其运行一些方法。
所以我在元类中创建了key_type 一个属性:
class Key: pass
class OtherKey: pass
class MetaFoo(type):
_key_type = None
@property
def key_type(cls):
return cls._key_type
@key_type.setter
def key_type(cls, value):
print(f'Setting key_type to {value}')
cls._key_type = value
class Foo(metaclass=MetaFoo):
key_type = Key
if __name__ == "__main__":
print(f"Foo's key type: {Foo.key_type}")
Foo.key_type = OtherKey
print(f"Foo's key type: {Foo.key_type}")
输出:
Foo's key type: None
Setting key_type to <class '__main__.OtherKey'>
Foo's key type: <class '__main__.OtherKey'>
似乎元类中_key_type 的定义覆盖了主类中key_type 的定义。但最重要的是,没有使用 Key 类型调用 setter。
预期输出:
Setting key_type to <class '__main__.Key'>
Foo's key type: <class '__main__.Key'>
Setting key_type to <class '__main__.OtherKey'>
Foo's key type: <class '__main__.OtherKey'>
(*) 我也希望它在初始化时发生的原因是 Foo 可以继承自。我想知道(在 MetaFoo 或 Foo 中)子类是否使用不同的 key_type。
【问题讨论】:
-
请注意,类主体分配给一个临时类命名空间。您可能想检查提供给 type.__prepare__ 命名空间的键是否实际分配,而不仅仅是复制。
-
确实;
key_type的初始分配发生在元类的实例(即您的类Foo)拥有属性之前。您只是分配了一个名称,该名称将在调用元类后成为属性。
标签: python