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