Ricardo Vilaça
Ricardo Vilaça

Reputation: 1006

Update class variable (dict) with new dict

class Content(Component):
    context = {
        'loading_circle': LoadingCircle(),
        'error_message': ErrorMessage(),
        'components': [],
    }

    def __init__(self, context = context):
        super().__init__()

In this class, if i want to create a new instance with some diferent components, i would have to call:

context = {
    'loading_circle': LoadingCircle(),
    'error_message': ErrorMessage(),
    'components': ['example component'],
}

Content(context = context)

But this means i'll have to always include loading_circle and error_message keys on my context..

I want to be able to do:

context = {
    'components': ['example component'],
}
Content(context = context)

.. And still have the default value for loading_circle and error_message.

I know i could change the __init__ method:

    def __init__(self, context = context):
        for key, value in context.items():
            self.context[key] = value
        
        super().__init__()

But for some reason it doesn't seems pythonic.

What would an experienced programmer change here? (Or is it this indeed the best solution?)

Upvotes: 0

Views: 86

Answers (1)

user2390182
user2390182

Reputation: 73498

I would not have conflicting names for class and instance variables and also avoid mutable default arguments:

class Content(Component):
    defaults = {
        'loading_circle': LoadingCircle(),
        'error_message': ErrorMessage(),
        'components': [],
    }

    def __init__(self, context=None):  # no mutable default args!
        super().__init__()
        self.context = {**self.defaults, **(context or {})}

This way, every instance has its own context with the class providing said context's defaults.

Note that in the {**d1, **d2} expression, any key present in d2 will "override" the same key from d1.

Upvotes: 3

Related Questions