可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.