Newbie: anything resembling static?

Alex Martelli aleax at aleax.it
Sun Feb 2 05:43:56 EST 2003


Tom wrote:
   ...
>> def five():
>>     staticvar = []
>>     def innerfive():
>>         staticvar.append('x')
>>         return ''.join(staticvar)
>>     return innerfive
>> five = five()
> 
> I've played around with the several options in Alex's msg and learned
> some things I didn't know about nested scopes.  (Thanks, Alex.)  I

You're welcome!

> also read PEP 227 (and understood many parts of it), but I still have
> one question: after I've called the function 'five' several times, is
> there a way to see the current value of 'staticvar' in an interactive
> session?

I don't think there's any way to get back to it (I haven't looked
deeply into it and would love to be proved wrong!): five does
know the names of its free variables, but their values it gets
via a "cell" object that, AFAIK, offers no accessibility from Python:

>>> five.func_code.co_freevars
('staticvar',)
>>> five.func_closure
(<cell at 0x4019629c: list object at 0x401b7d8c>,)
>>> dir(five.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__new__', '__reduce__', '__repr__',
'__setattr__', '__str__']


> I understand why 'five.innerfive.staticvar' doesn't work.  What will?
> Don't have any use case in mind, just curious.

If you DO need more sophisticated access to a bundle of
code and data, compared with what simple closures afford,
then it may be worth the slight complication of defining
a class for the purpose, as others have suggested: a class
is the "royal road" to bundling code and data for general
purposes -- closures only simplify your life for simple
(but important) special cases.

That much being said, it doesn't take much to tweak the
code to give you what you want -- just add ONE line...:

>> def five():
>>     staticvar = []
>>     def innerfive():
>>         staticvar.append('x')
>>         return ''.join(staticvar)
       innerfive.staticvar = staticvar
>>     return innerfive
>> five = five()

there -- NOW you can check on five.staticvar from the interactive
session, or wherever -- NOT five.innerfive.whatever -- the _name_
"innerfive" has now disappeared, as it was a local name of the
outer function whose name ('five') we've rebound to the inner...


Alex





More information about the Python-list mailing list