繁体   English   中英

你可以动态地将类属性/变量添加到 python 中的子类吗?

[英]Can you dynamically add class attributes/variables to a subclass in python?

我在 python 中有大量自动生成的类,它们基本上代表通信协议的一部分的枚举,它们看起来像这样

# definitions.py

class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3

class AlpacaType(ParamEnum):
    Fuzzy = 0
    ReallyMean = 1

# etc etc etc

以这种方式定义事物使自动生成器和人类更容易修改。 ParamEnum 类提供所有功能、获取/设置、比较、转换和从传入网络数据创建等。

但是,这些类需要一些额外的元数据。 希望添加这个到每个类,但是源定义,因为它使得它的可读性和将打破自动发生器

目前我正在这样做

# param_enum.py

class ParamEnum(object):
    def __init__(self):
        self.__class__._metadata = get_class_metadata(self.__class__)

然而这让我觉得有些低效,因为每次我们实例化这些枚举之一时都会发生这种情况(经常发生),而不仅仅是定义(元数据不会改变,所以它只需要设置一次)

我尝试将其添加到定义文件的底部,但在那里也遇到了问题。

class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3

for var in locals():  # or globals? 
    add_metadata(var)
    #doesn't work because it is in the same file, modifying dict while iteratng

python中有没有办法在定义类时覆盖/添加功能,可以继承到子类? 理想情况下,我想要类似的东西

class ParamEnum(object):
    def __when_class_defined__(cls):
        add_metadata(cls)

使用类装饰器

def add_metadata(cls):
    cls._metadata = get_class_metadata(cls)
    return cls

@add_metadata
class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3

实际上,您想要做的正是拥有装饰器的动机:在创建类或函数后对其进行修改。

如果您不熟悉装饰器,请阅读本文(虽然有点冗长)。

您也可以使用元类,但它们比装饰器引入了更多的复杂性。 如果您想避免额外的修饰行@add_metadata并且您认为它相对于指定的子类ParamEnum是多余的,您还可以使_metadata 成为基类ParamEnum具有延迟评估的描述符

class MetadataDescriptor(object):
    def __get__(self, obj, cls):
        if cls._metadata_value is None:
            cls._metadata_value = get_class_metadata(cls)
        return cls._metadata_value

class ParamEnum(object):
    _metadata_value = None
    _metadata = MetadataDescriptor()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM