[英]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.