0

I have a command line utility which can accept various commands what to do, so basically there is a big elif chain what command will be executed. Some of the commands use variable (lets call it A) so it has to be initialized with a value. So normally I would do:

self.A = createContent()
doSomething(self.A.B)

Now I don't want to put self.A = createContent() for every command where the A is needed so I would like to ask if there is a way in Python how to initialize the variable automatically when its None for example. The createContent takes time to process so I don't want to put it into constructor which gets executed for every command.

2
  • 1
    This question is rather confusing. I think we need more context to understand what exactly you're trying to do and why that way would be the right way to do it. For example, what kind of an object is self, and couldn't you just use that object's initialisation method to define A? Commented Oct 30, 2014 at 7:49
  • I will try to expain it better: I have an object, during single lifetime of the object, the A is sometimes needed, and sometimes not at all. I don't want to use object's initialization method because defining A is expensive and it is not always needed. At the same time I don't want to do checking whether it is not defined and define it on all the places where the A is needed. Commented Oct 30, 2014 at 8:19

4 Answers 4

1

What about hasattr?

if not hasattr(self, 'A') or self.A is None:
    self.A = createContent()
0

If initialization is expensive, and you therefore only want to initialize the variable when it's needed, one Pythonic way would be to simply try to use it, and if that fails, initialize it.

For example:

try:
    do_something(self.A)
except AttributeError:
    self.A = initialize(self)
    do_something(self.A)

You would need to wrap every line of code that uses A in a situation where you can't be sure that it isn't defined yet in such a try/except block.

The other way would be to do an explicit check for A every time like @Nsh has proposed. But somebody, either you or Python, will have to do the checking at some point.

0

Assuming your attribute self.A is some sort of static object, we can implement it using a property that creates it on demand:

class Something(object):
    @property
    def A(self):
        try:
            return self._A
        except AttributeError:
            self._A=CreateAnA()
            return self._A

This way you don't need to duplicate the check. You could add a setter etc if you need those operations. The downside is primarily that it's not obvious when you do create it (as it's a side effect of reading an attribute), and there's a slight performance penalty for the indirect lookup (which could be avoided using __getattr__, at the expense of other failed lookups).

0

Thanks to the suggestions above, I came up with this:

class myClass:
    def __getattr__(self,name):
        if name == 'attributeA':
            print "initializing A"
            self.attributeA = self.expensiveInit()
            return self.attributeA
    def doStuff(self):
        print self.attributeA
    def expensiveInit(self):
        return 'gold'


a = myClass()
a.doStuff()
a.doStuff()
a.doStuff()

Do you think this is correct/pythonic?

1
  • That __getattr__ will cause all undefined names to produce None. The normal behaviour if you don't find anything is to raise AttributeError. Commented Oct 30, 2014 at 14:10

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