簡體   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