One way is to give the function itself an attribute which will only be True on the first call.
>>> def once(): ... if once.first_call: ... print('doing some heavy computation over here...') ... once.result = 1 + 1 ... once.first_call = False ... return once.result ... >>> once.first_call = True >>> once() doing some heavy computation over here... 2 >>> once() 2
Another option is to (ab)use a mutable default parameter. The advantage is that you don't have to set an attribute on the function after defining it:
>>> def once(state={'first_call':True}): ... if state['first_call']: ... print('doing some heavy computation over here...') ... state['result'] = 1 + 1 ... state['first_call'] = False ... return state['result'] ... >>> once() doing some heavy computation over here... 2 >>> once() 2
edit:
For completeness, if you have instance attributes that should only be computed once, use a property:
class Foo(object): def __init__(self): self._x = None @property def x(self): if self._x is None: self._x = self._compute_x() return self._x def _compute_x(self): print('doing some heavy computation over here...') return 1 + 1
Demo:
>>> f = Foo() >>> f.x doing some heavy computation over here... 2 >>> f.x 2