Python Enum combination

391
September 06, 2017, at 9:31 PM

I would like to create a new Enum (IntEnum) class based on two existing ones. There is a working solution for this, like so:

from enum import unique, IntEnum
from itertools import chain
from collections import OrderedDict
@unique
class FirstEnumClass(IntEnum):
    a = 1
    b = 2
@unique
class SecondEnumClass(IntEnum):
    c = 3
    d = 4
# here a combined class is created:
CombinedEnumClass = unique(IntEnum('CombinedEnumClass', OrderedDict([(i.name, i.value) for i in chain(FirstEnumClass, SecondEnumClass)])))

My question: is there a fancy way to achieve this, so that there is a proper class definition? Like overriding some of the metaclass methods, or so? I would like something like this, so that docstring can also be given:

@unique
class CombinedEnumClass(IntEnum):
    """ docstring """
    # magic needed here

Any idea? Thanks!

Answer 1

The library prevents explicitly to do that:

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. On the other hand, it makes sense to allow sharing some common behavior between a group of enumerations.

Therefore, I found a Stackoverflow answer using almost the same workaround as you do. I think this is the only way.

Answer 2

Using a trick with vars() this can be accomplished:

class CombinedEnum(IntEnum):
    """ doc string """
    cls = vars()
    for member in chain(list(FirstEnumClass), list(SecondEnumClass)):
        cls[member.name] = member.value
    del member, cls
print(list(CombinedEnum))

This works because:

  • vars() returns the current namespace
  • modifying that namespace modifies the class

We delete member and cls because we don't want them to become members.

READ ALSO
aws emr python script logs not stored in s3

aws emr python script logs not stored in s3

I have a python application that I run on emr cluster through spark-submit command and I donĀ“t get any log in stdout or stderr

207
matplotlib animation close event

matplotlib animation close event

I uses the animationFuncAnimation from matplotlib to view camera pictures

486
Python-Flask-SQLAlchemy Get date column in ISO format

Python-Flask-SQLAlchemy Get date column in ISO format

I have a model class which looks like this

427