我有一个数据类A,它可以被继承并用于创建其他类。每当我的类A继承时,我都希望将子类注册到容器中。我想用元类解决它,但是对我来说不起作用。有什么帮助吗?
container = {}
class Meta(type):
def __new__(mcs, *args, **kwargs):
new_class = super().__new__(mcs, *args, **kwargs)
if new_class.__name__ != 'A':
container[new_class.__name__] = new_class
return new_class
@metaclass
class MasterClass:
parent
@metaclass
class A(MasterClass, metaclass=Meta):
my_arg
@metaclass
class Child(A): # <-- this class I would like to register into child container
my_next_arg
您的代码几乎是正确的,但是当使用“ @metaclass”作为“ @dataclass”修饰符,并在字段上创建一些注释时,没有NameError异常。
所以,如果您只是这样做:
from dataclasses import dataclass
from typing import Any
container = {}
class Meta(type):
def __new__(mcs, *args, **kwargs):
new_class = super().__new__(mcs, *args, **kwargs)
if new_class.__name__ != 'A':
container[new_class.__name__] = new_class
return new_class
@dataclass
class MasterClass:
parent: Any
@dataclass
class A(MasterClass, metaclass=Meta):
my_arg: Any
@dataclass
class Child(A): # <-- this class I would like to register into child container
my_next_arg: Any
它将按您期望的方式工作,并且Child
将被注册到容器:
In [5]: container
Out[5]: {'Child': __main__.Child}
只需注意,从Python 3.6开始,您不需要使用元类对于此模式,称为__init_subclass__
类方法关于子类的创建,并且可以做到相同:
from dataclasses import dataclass
from typing import Any
container = {}
@dataclass
class MasterClass:
parent: Any
@dataclass
class A(MasterClass):
def __init_subclass__(cls, *args, **kw):
super().__init_subclass__(*args, **kw)
container[cls.__name__] = cls
my_arg: Any
@dataclass
class Child(A): # <-- this class I would like to register into child container
my_next_arg: Any