1

This popular question addresses setting instance attributes with keyword arguments. However, I'd like to construct a class whose instances all have the same attributes based on some dictionary. How can this be achieved?

Here's my attempt. It seems I haven't quite understood something about class definitions.

d = {'x': 1, 'y': 2}


# Here's what I'd like to do
class A:
    __dict__ = d


# Answer from the linked question that works
class B:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)


a = A()
b = B(**d)

# print(A.x)  # Has no attribute x
# print(a.x)  # Has no attribute x
print(b.x)

This is curious, because both a.__dict__ and b.__dict__ return the same thing.

Felix
  • 2,548
  • 19
  • 48
  • I'm not sure I understand the question. Do you want to create a new class programmatically, with attributes based on the `dict` provided, so that all instances of the class will have those attributes? – gmds May 16 '19 at 11:51
  • @gmds Yes. My bad if it wasn't immediately clear. – Felix May 16 '19 at 11:51
  • 1
    What sense does is make to have all instances have the same attributes? What would be a valid use-case? – Klaus D. May 16 '19 at 11:55
  • @KlausD. Using the class as a type of dynamic data storage. For me, creating a Flask configuration object. There may be better ways, after all there already exists such a method for utilising dictionaries: `from_mapping`. But as I started to look for the solution my question was "can I" rather than "should I". I love learning myself some new Python. – Felix May 16 '19 at 11:58

1 Answers1

0

The type function can take arguments that allow it to create a new class dynamically:

B = type('B', (), d)

b = B()

print(b.x, b.y)

Output:

1 2

The first argument is the name of the generated class. The second is a tuple containing its base classes. In particular, the following two snippets are (roughly) equivalent:

class D(A, B, C):
    pass

and:

D = type('D', (A, B, C), {})

The last argument is a dict mapping names to attributes (both methods and values).

gmds
  • 19,325
  • 4
  • 32
  • 58