How to extend Python Enum?
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-enum-subclassing
So no, it's not directly possible.
While uncommon, it is sometimes useful to create an enum from many modules. The aenum
1 library supports this with an extend_enum
function:
from aenum import Enum, extend_enumclass Index(Enum): DeviceType = 0x1000 ErrorRegister = 0x1001for name, value in ( ('ControlWord', 0x6040), ('StatusWord', 0x6041), ('OperationMode', 0x6060), ): extend_enum(Index, name, value)assert len(Index) == 5assert list(Index) == [Index.DeviceType, Index.ErrorRegister, Index.ControlWord, Index.StatusWord, Index.OperationMode]assert Index.DeviceType.value == 0x1000assert Index.StatusWord.value == 0x6041
1 Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.
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 IntEnumclass IndexGeneric(IntEnum): """ This enum holds the index value of genric object entrys """ DeviceType = 0x1000 ErrorRegister = 0x1001Idx = IndexGeneric
drives.py:
from itertools import chainfrom enum import IntEnumfrom nodes import IndexGenericclass IndexDrives(IntEnum): """ This enum holds the index value of drive object entrys """ ControlWord = 0x6040 StatusWord = 0x6041 OperationMode = 0x6060Idx= IntEnum('Idx', [(i.name, i.value) for i in chain(IndexGeneric,IndexDrives)])