Search code examples
pythonpython-3.xclass

Class object: adding attributes to class based on an input list


Say I have the following simple Class object

class TEST:

    def __init__(self, project = 'ABC', scenarios = {'A': [1,2,3], 'B': [4,5,6]}):

        self.project = project
        self.scenarios = scenarios


P = TEST(project = 'ABC', scenarios = {'A': [1,2,3], 'B': [4,5,6]})

print(P.scenarios)

{'A': [1, 2, 3], 'B': [4, 5, 6]}

What I want: Using the example above, I want to be able to specify:

P = TEST(project = 'ABC', scenarios = {'A': [1,2,3], 'B': [4,5,6], 'C': [7,8,9]})

and be able to return the following output

In [2]:P.A
Out[2]: [1, 2, 3]

In [3]:P.B
Out[4]: [4, 5, 6]

In [3]:P.C
Out[4]: [7, 8, 9]

That is, I want to automatically add the dictionary keys as attributes and have them return the values of the dictionary.

What I've tried: This is similar to how a Pandas DataFrame automatically adds the column names as attributes and returns the series. I've tried combing through the backend code there but no luck.

This SO question was helpful, but I wasn't able to get anywhere with it because I wasn't able to figure out a way to add it as an attribute (e.g. self. + scenarios.keys(), etc)


Solution

  • You could just update the instance's __dict__ with scenarios:

    class TEST:
        def __init__(self, project='ABC', scenarios=None):
            self.project = project
            self.scenarios = scenarios or {'A': [1, 2, 3], 'B': [4, 5, 6]}
            self.__dict__.update(self.scenarios)
    
    >>> P = TEST(project='ABC', scenarios={'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
    >>> P.A
    [1, 2, 3]
    >>> P.B
    [4, 5, 6]
    >>> P.C
    [7, 8, 9]
    

    BTW, this might not be your real code, but avoid mutable default arguments unless you are sure what you are doing.