1

I have a class which inherits from Enum and str. I need to define some class attributes which are defined in a .json file and is being loaded in a Python dictionary.

from enum import Enum

# I want to create a class like this (but assign the class attributes by reading a dict)

class Test(str, Enum):
  A = 'Alpha'
  B = 'Beta'

# Attempt to solve :

mydict = { 'A' : 'Alpha', 'B' : 'Beta' }

class Test1(str, Enum):
  for k,v in mydict.items():
    k = v

# => An Error is reported here.

For class instances, I can use setattr() but I could not find anything to set the class attributes.

Since these attributes are dynamic and could change, I do not want to hard-code the class attributes but rather read in a dictionary and set it.

sarbjit
  • 3,786
  • 9
  • 38
  • 60
  • 2
    Does this answer your question? [How can I construct an enum.Enum from a dictionary of values?](https://stackoverflow.com/questions/47299036/how-can-i-construct-an-enum-enum-from-a-dictionary-of-values) – kederrac Apr 12 '20 at 21:42

5 Answers5

2

Don't define your own class directly, instead use the Enum functional API:

Test = enum.Enum("Test", mydict, type=str)
Blckknght
  • 100,903
  • 11
  • 120
  • 169
1

You can use setattr() too for classes:

>>> class A: 
...     pass
...
>>> setattr(A, "attribute", 3)
>>> inst = A()
>>> inst.attribute
3

Just iterate through the dict like this:

for k, v in mydict.items():
     setattr(Test, k, v)
  • This will not work properly for an Enum class. It creates class attributes, but they won't become Enum objects, they'll just be whatever value you set (so you lose the benefits of using `Enum`). – Blckknght Apr 12 '20 at 21:48
1

To make this dynamic, you can set all attributes under __new__ magic function. An example of this is here:

attr_dict ={
    'A': 'alpha',
    'B': 'beta'
}

class MyClass:
    def __new__(cls, *args, **kwargs):
        for k, v in attr_dict.items():
            setattr(cls, k, v)
        return cls

x = MyClass()

x.A  # --> 'alpha'
x.B  # --> 'beta'
Sazzy
  • 1,924
  • 3
  • 19
  • 27
0

This answer should help you.

From answer:

Python 3

for k, v in mydict.items():
    exec("%s=%s" % (k,v))

That doesn't smell like good practice, but works.

João Victor
  • 407
  • 2
  • 10
  • 1
    This does not work. Not in general, if your values don't have a `str` value that reproduces them, nor will it work properly in the body of an `Enum` class, as you can't put the loop in there (it raises an error about reusing the key `k`). – Blckknght Apr 12 '20 at 21:46
0

Python 3

    class MyClass:
        def __init__(self, **kwargs):
            self.__dict__.update(kwargs)
    
    attr_dict ={
        'A': 'alpha',
        'B': 'beta'
    }
    
    my_class = MyClass(**attr_dict)
    print(my_class.__dict__)
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 03 '23 at 05:15