How to extend Python Enum?

匿名 (未验证) 提交于 2019-12-03 02:23:02

问题:

What is best practice for extending Enum type in Python 3.4 and is there even a possibility for do this?

For example:

from enum import Enum  class EventStatus(Enum):    success = 0    failure = 1  class BookingStatus(EventStatus):    duplicate = 2    unknown = 3  Traceback (most recent call last): ... TypeError: Cannot extend enumerations 

Currently there is no possible way to create a base enum class with members and use it in other enum classes (like in the example above). Is there any other way to implement inheritance for Python enums?

回答1:

Subclassing an enumeration is allowed only if the enumeration does not define any members.

Allowing subclassing of enums that define members would lead to a violation of some important invariants of types and instances.

https://docs.python.org/3/library/enum.html#restricted-subclassing-of-enumerations

So no, it's not directly possible.



回答2:

Calling the Enum class directly and making use of chain allows the extension (joining) of an existing enum.

I came upon the problem of extending enums while working on a CANopen implementation. Parameter indices in the range from 0x1000 to 0x2000 are generic to all CANopen nodes while e.g. the range from 0x6000 onwards depends open whether the node is a drive, io-module, etc.

nodes.py:

from enum import IntEnum  class IndexGeneric(IntEnum):     """ This enum holds the index value of genric object entrys     """     DeviceType    = 0x1000     ErrorRegister = 0x1001  Idx = IndexGeneric 

drives.py:

from itertools import chain from enum import IntEnum from nodes import IndexGeneric  class IndexDrives(IntEnum):     """ This enum holds the index value of drive object entrys     """     ControlWord   = 0x6040     StatusWord    = 0x6041     OperationMode = 0x6060  Idx= IntEnum('Idx', [(i.name, i.value) for i in chain(IndexGeneric,IndexDrives)]) 


回答3:

While uncommon, it is sometimes useful to create an enum from many modules. The aenum1 library supports this with an extend_enum function:

from aenum import Enum, extend_enum  class Index(Enum):     DeviceType    = 0x1000     ErrorRegister = 0x1001  for name, value in (         ('ControlWord', 0x6040),         ('StatusWord', 0x6041),         ('OperationMode', 0x6060),         ):     extend_enum(Index, name, value)  assert len(Index) == 5 assert list(Index) == [Index.DeviceType, Index.ErrorRegister, Index.ControlWord, Index.StatusWord, Index.OperationMode] assert Index.DeviceType.value == 0x1000 assert Index.StatusWord.value == 0x6041 

1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!