[英]Add and initilalize an enum class variable in Python
I'm implementing an enum
class
and want to retrieve an aggregate information about the enum
members.我正在实现一个enum
class
并希望检索有关enum
成员的聚合信息。 Each enum
represents a breakout board with different number of pins, and I want to get the maximum number of pins over all boards.每个enum
代表一个具有不同引脚数的分线板,我想获得所有板上的最大引脚数。 My approach was to add a class attribute _max_pins which is adjusted during __init__
of each member.我的方法是添加一个类属性 _max_pins,该属性在每个成员的__init__
期间进行调整。
Problem is, it is not possible to define _max_pins ahead if the members as it would become a member, too.问题是,如果成员也将成为成员,则不可能提前定义 _max_pins。 It does not help to define it after the members as then the members cannot access it during their __init__
I've looked at Declare a static variable in an enum class but the table can be set up after __init__
- that would be possible but would need to scan again all members after their initialization.在成员之后定义它并没有帮助,因为成员在他们的__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
Above code produces UnboundLocalError: local variable '_max_pin' referenced before assignment
上面的代码产生UnboundLocalError: local variable '_max_pin' referenced before assignment
When I move the assignment of _max_pin in front of the member definition it tells me that TypeError: __init__() missing 2 required positional arguments: ...
当我在成员定义前移动 _max_pin 的赋值时,它告诉我TypeError: __init__() missing 2 required positional arguments: ...
Edit 1 Actually, the TypeError
is raised regardless where I put the assignment within the class.编辑 1实际上,无论我将作业放在类中的哪个位置,都会TypeError
。 And when I use IgelTyp._max_pin = -1
I get a NameError: name 'IgelTyp' is not defined
当我使用IgelTyp._max_pin = -1
我得到一个NameError: name 'IgelTyp' is not defined
Anyone has an efficient and readable solution?任何人都有一个有效且可读的解决方案?
One-off solution:一次性解决方案:
Change your __init__
to directly access the class's dictionary:更改您的__init__
以直接访问类的字典:
def __init__(self, pins, groups):
max_pin = self.__class__.__dict__.get('max_pin', 0)
self.__class__.max_pin = max(max_pin, pins//groups)
Interestingly, you could easily have each LED member store its own max_pin
by adding this line at the end of __init__
:有趣的是,您可以通过在__init__
末尾添加以下行轻松让每个 LED 成员存储自己的max_pin
:
self.max_pin = pins//groups
so:所以:
>>> IgelTyp.max_pin
24
but:但:
>>> IgelType.LED_2.max_pin
12
Reusable solution可重复使用的解决方案
Create your own class attribute descriptor, and use that to shield max_pin
from becoming an IgelTyp
member:创建您自己的类属性描述符,并使用它来防止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
Descriptors, such as property
usually store the value on the instance itself so that each instance can have it's own value (such as 24, 12, and 4 from your example);描述符(例如property
通常将值存储在实例本身上,以便每个实例都可以拥有自己的值(例如示例中的 24、12 和 4); however, since you want to know the maximum number of pins across all instances, we just save that single value on the ClassVar
instance.但是,由于您想知道所有实例的最大引脚数,我们只在ClassVar
实例中保存该单个值。
The changes to IgelTyp
:对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)
and in use:并在使用中:
>>> IgelTyp.max_pin
24
>>> IgelTyp.LED_2.max_pin
24
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.