1

I hav a class which needs to initialize 4 variables returned by a load() function. And in the future the load may return even more variable values. This is my current way of initializing the Runner class. Is there a more normal way or better way to do this?

class Runner(object):
    
    def __init__(self):
        self.first, self.second, self.third, self.mapping = self.load()

    def load():
       ...
     return (first, second, third, mapping)
2
  • 1
    I'd recommend initializing the attributes as whatever type they'll end up, and use self.load() to set the values of those variables. You COULD use setattr() in a for loop but that's generally not a good idea. You could also try returning a dict from load() and self.__dict__ = {**self.__dict__, **self.load()} but I haven't tried that to confirm.
    – ddejohn
    Commented Aug 24, 2021 at 20:11
  • To be honest, it's hard for me to think of something simpler than that. Commented Aug 24, 2021 at 20:12

2 Answers 2

2

If you will have a very large number of such variables, they should not be variables but keys in a dictionary. The way you're going, you'll have to keep track in two separate places of what each position stands for (what's the fifth variable, the sixth variable, etc.), and always keep them in sync -- and that's just one of the problems.

So use a dictionary, change load() to return a dictionary as well, and it all boils down to how to pass and copy dictionaries; for which there are many concise solutions.

0

You could create a method to drive the process as illustrated by the attrs_from_dict() method shown below. Done this way, the load() method effectively determines what attributes are added by way of the keys in the dictionary it returns.

class Runner(object):
    def __init__(self):
        self.attrs_from_dict(self.load())

    def attrs_from_dict(self, d):
        for k, v in d.items():
            setattr(self, k, v)

    def load(self):
        return dict(first=1, second=2, third=3, mapping=dict(ans=42))


runner = Runner()

print(vars(runner))  # -> {'first': 1, 'second': 2, 'third': 3, 'mapping': {'ans': 42}}

Not the answer you're looking for? Browse other questions tagged or ask your own question.