[英]Add and initilalize an enum class variable in Python
我正在實現一個enum
class
並希望檢索有關enum
成員的聚合信息。 每個enum
代表一個具有不同引腳數的分線板,我想獲得所有板上的最大引腳數。 我的方法是添加一個類屬性 _max_pins,該屬性在每個成員的__init__
期間進行調整。
問題是,如果成員也將成為成員,則不可能提前定義 _max_pins。 在成員之后定義它並沒有幫助,因為成員在他們的__init__
期間無法訪問它我看過在枚舉類中聲明一個靜態變量但是可以在__init__
之后設置表 - 這可能但需要初始化后再次掃描所有成員。
class IgelTyp(Enum):
LED_1 = (24, 1)
LED_2 = (24, 2)
LED_3 = (16, 4)
_max_pin = -1
def __init__(self, pins, groups):
if _max_pin < pins//groups: # gives error
_max_pin = pins//groups
@classmethod
def get_max_pins(cls):
return cls._max_pin
上面的代碼產生UnboundLocalError: local variable '_max_pin' referenced before assignment
當我在成員定義前移動 _max_pin 的賦值時,它告訴我TypeError: __init__() missing 2 required positional arguments: ...
編輯 1實際上,無論我將作業放在類中的哪個位置,都會TypeError
。 當我使用IgelTyp._max_pin = -1
我得到一個NameError: name 'IgelTyp' is not defined
任何人都有一個有效且可讀的解決方案?
一次性解決方案:
更改您的__init__
以直接訪問類的字典:
def __init__(self, pins, groups):
max_pin = self.__class__.__dict__.get('max_pin', 0)
self.__class__.max_pin = max(max_pin, pins//groups)
有趣的是,您可以通過在__init__
末尾添加以下行輕松讓每個 LED 成員存儲自己的max_pin
:
self.max_pin = pins//groups
所以:
>>> IgelTyp.max_pin
24
但:
>>> IgelType.LED_2.max_pin
12
可重復使用的解決方案
創建您自己的類屬性描述符,並使用它來防止max_pin
成為IgelTyp
成員:
class ClassVar: # add (object) if using Python 2
"a class variable"
def __init__(self, value):
# store initial value
self.value = value
def __get__(self, *args):
# get value in ClassVar instance (only doable because all instances
# share same value)
return self.value
def __set__(self, _, value):
# save value in ClassVar instance (only doable because all instances
# share same value)
self.value = value
描述符(例如property
通常將值存儲在實例本身上,以便每個實例都可以擁有自己的值(例如示例中的 24、12 和 4); 但是,由於您想知道所有實例的最大引腳數,我們只在ClassVar
實例中保存該單個值。
對IgelTyp
的更改:
class IgelTyp(Enum):
LED_1 = (24, 1)
LED_2 = (24, 2)
LED_3 = (16, 4)
max_pin = ClassVar(0)
def __init__(self, pins, groups):
self.max_pin = max(self.max_pin, pins//groups)
並在使用中:
>>> IgelTyp.max_pin
24
>>> IgelTyp.LED_2.max_pin
24
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.