声明类属性时如何触发 setter?



我有一个类;我们称之为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类型。

预期产出:

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

class Fookey_type的定义实际上在第三个参数(这是一个字典)中添加了一个键值对,用于初始化MetaFoo,除此之外它不会做任何事情。

因此,您可以操作MetaFoo的初始化以显式调用 setter 方法。这可以通过重写元类__init__方法来完成:

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
def __init__(self, name, bases, kw):
super(MetaFoo, self).__init__(name, bases, kw)
for key, val in kw.items():
setattr(self, key, val)

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}")

输出:

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'>

最新更新