0

Supppose I have the following enum class:

from enum import Enum, unique

@unique
class Indication(Enum):
    Fruit1 = 'apple'
    Fruit2 = 'orange'
    Fruit3 = 'banana'

Is want to generate this enum class from a python list, i.e.

Listoffruits = [('Fruit1', 'apple'),  ('Fruit2', 'orange'), ('Fruit3',  'banana')]

How can this be done effectively?

  • Does this answer your question? [Dynamically create an enum with custom values in Python?](https://stackoverflow.com/questions/33690064/dynamically-create-an-enum-with-custom-values-in-python) – awesoon May 31 '20 at 18:31

2 Answers2

1

Use the Functional API if you want to dynamically define an Enum:

import enum

Listoffruits = [('Fruit1', 'apple'),  ('Fruit2', 'orange'), ('Fruit3',  'banana')]

Indication = enum.Enum('Indication', dict(Listoffruits))

You can use string formatting to "generate" the Python code:

def generate_enum(enumClass, enumDict):
    """
    Generates python code for an Enum
    """

    enum_template = """
@unique
class {enumClass}(Enum)
{enumBody}
"""

    enumBody = '\n'.join([f"    {name} = '{value}'" for (name,value) in enumDict.items()])

    return enum_template.format(enumClass=enumClass,enumBody=enumBody)

print(generate_enum('Indication',dict(Listoffruits)))

The generated code will be:

@unique
class Indication(Enum)
    Fruit1 = 'apple'
    Fruit2 = 'orange'
    Fruit3 = 'banana'
  • You don't need to convert a list of tuples to dict before passing to `enum.Enum`. Also your second solution just generates a string with enum class, but you'll need to evaluate it before using in your code. Is it any better than enum functional api approach? – awesoon Jun 01 '20 at 07:56
0

Enum docs mentions a functional API. So you can just do:

from enum import Enum
Indication = Enum('Indication', dict(Listoffruits))

Proof:

>>> list(Indication)
[<Indication.Fruit1: 'apple'>,
 <Indication.Fruit2: 'orange'>,
 <Indication.Fruit3: 'banana'>]

As a matter of exploring Python, you can consider how this hack works (it does):

from enum import Enum, unique

def inject_items(d, items):
    for k, v in items:
        d[k] = v

@unique
class Indication(Enum):
    inject_items(locals(), Listoffruits)

But that's just for educational purposes. I'd use Enum's functional API for you purpose.

thorwhalen
  • 1,920
  • 14
  • 26