"once" assigment in Python

Peter Otten __peter__ at web.de
Fri Sep 14 03:40:47 EDT 2007


Lorenzo Di Gregorio wrote:

> I've been using Python for some DES simulations because we don't need
> full C speed and it's so much faster for writing models.  During
> coding I find it handy to assign a variable *unless it has been
> already assigned*: I've found that this is often referred to as "once"
> assigment.
> 
> The best I could come up with in Python is:
> 
> try:
>   variable
> except NameError:
>   variable = method()
> 
> I wonder if sombody has a solution (trick, whatever ...) which looks
> more compact in coding.  Something like:
> 
> once(variable, method)
> 
> doesn't work, but it would be perfect.  Of course I can preprocess the
> Python code but an all-Python solution would be more handy.
> 
> Any suggestions?

You can use properties to implement lazy evaluation. Or you can rely on a
naming convention:

>>> class Once(object):
...     def __getattr__(self, name):
...             if name.startswith("_calc_"):
...                     raise AttributeError("No method to calculate attribute %r" % name[6:])
...             value = getattr(self, "_calc_" + name)()
...             setattr(self, name, value)
...             return value
... 
>>> class A(Once):
...     def _calc_foo(self):
...             print "calculating foo"
...             return 42
... 
>>> a = A()
>>> a.foo
calculating foo
42
>>> a.foo
42
>>> a.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __getattr__
  File "<stdin>", line 4, in __getattr__
AttributeError: No method to calculate attribute 'bar'
>>> a._calc_bar = lambda: "bar-value"
>>> a.bar
'bar-value'

Peter



More information about the Python-list mailing list