简体   繁体   English

在 Python 中添加和初始化枚举类变量

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM