C-style static variables in Python?

kj no.email at please.post
Thu Apr 1 18:34:31 EDT 2010



When coding C I have often found static local variables useful for
doing once-only run-time initializations.  For example:

int foo(int x, int y, int z) {

  static int first_time = TRUE;
  static Mongo *mongo;
  if (first_time) {
    mongo = heavy_lifting_at_runtime();
    first_time = FALSE;
  }

  return frobnicate(mongo, x, y, z);
}

In this case, the static variable mongo is initialized only once
(at most).

What I like most about this is that it obviates the need for a
global variable to hold the persistent value (I avoid globals like
the plague, especially in Python).  It also nicely encapsulates
the logic that determines whether initialization is required.

The best way I've found to achieve a similar effect in (procedural)
Python defines the function as a closure.  For example, here's a
function that keeps track of (and prints out) how many times it
has been called:

>>> def make_spam():
...     counter = [0]
...     def _():
...         counter[0] += 1
...         print counter[0]
...     return _
... 
>>> spam = make_spam()
>>> spam()
1
>>> spam()
2
>>> spam()
3

(Too bad that one can't stick the whole def inside parentheses and
call the function right there, like one can do with JavaScript.)

Another approach would be to stuff the static values in the function's
__dict__.  This is less satisfactory than the closure approach
because the "pseudo-static" variable is accessible from outside
the function, but the code is arguably a little more straightforward,
and one does not end up with the now useless one-time closure-generating
function kicking around.  Here's another version of the function
above:

>>> def spam():
...     d = spam.__dict__
...     if not 's' in spam.__dict__:
...         spam.s = 1 
...     print spam.s
...     spam.s += 1
... 
>>> spam()
1
>>> spam()
2
>>> spam()
3

Besides the external accessibility issue, I don't like explictly
coding the name of the function within the function.  Is there any
way to have the function access its own __dict__ without having to
explicitly code its name in its body?  E.g., is there some generic
special variable that, within a function, refers to the function
object itself?

I'm sure that there are many other ways to skin this cat, especially
if one starts definining fancy callable classes and whatnot.  But
is there a better *simple* way to achieve C-style static locals in
Python that does not require a lot of extra machinery?

TIA!

~K



More information about the Python-list mailing list