具有元类注册的数据类

问题描述 投票:0回答:1

我有一个数据类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

python metaclass python-3.8 python-dataclasses
1个回答
0
投票

您的代码几乎是正确的,但是当使用“ @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
© www.soinside.com 2019 - 2024. All rights reserved.