1

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)

Olvin Roght
  • 7,677
  • 2
  • 16
  • 35
measure_theory
  • 874
  • 10
  • 28

2 Answers2

1

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.

user2390182
  • 72,016
  • 6
  • 67
  • 89
1

First, have a look at this tiny usage of setattr() function which is used to define properties of modules, classes etc.

>>> class A:
...     pass
... 
>>> a = A()
>>> setattr(a, "prop1", 10)
>>> 
>>> a.prop1
10
>>> 
>>> setattr(a, "increment", lambda x: x + 1)
>>> 
>>> a.increment(110)
111
>>> 

Finally, you can try like this.

a is like self

prop1 is like feature i.e. A, B, C

scenario is like 10 i.e. [1, 2, 3], [4, 5, 6], [7, 8, 9]

>>> class TEST:
...     def __init__(self, project = 'ABC', scenarios = {'A': [1,2,3], 'B': [4,5,6]}):
...         self.project = project
...         for feature in scenarios:
...             scenario = scenarios[feature]
...             setattr(self, feature, scenario)
... 
>>> 
>>> 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]
>>> 

You can get mini help on your Python Interactive Terminal using help(setattr) which shows below.

Help on built-in function setattr in module builtins:

setattr(obj, name, value, /) Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''

hygull
  • 8,464
  • 2
  • 43
  • 52