Scoped change of a global variable

Alex Martelli aleax at aleax.it
Wed Jan 2 10:09:11 EST 2002


"Luigi Ballabio" <ballabio at mac.com> wrote in message
news:mailman.1009977602.11777.python-list at python.org...

I've also answered Luigi on the Italian list, but just in
case somebody else is following this in English, here's a
short summary of my response, translated back into English:

> # here is the store-and-set thing
> oldBaseCurrency = Currency.BaseCurrency
> Currency.BaseCurrency = EUR

# easy to further generalize, but, just as an example:
class TweakAttributes:
    def __init__(self, subject, **kwds):
        self.subject = subject
        self.saved = ()
        for name, value in kwds:
            self.saved.append((name, getattr(subject, name)))
            setattr(subject, name, value)
    def restore(self):
        for name, value in self.saved:
            setattr(self.subject, name, value)
        self.saved = ()    # ensure .restore is idempotent, just in case

saved = TweakAttributes(Currency, BaseCurrency=EUR)
try:
    # just indent all the calculations 4 spaces rightwards

> # here is the restore thing
> Currency.BaseCurrency = oldBaseCurrency

finally:
    saved.restore()


The try/finally ensures restoration happens even if some statement
in the try block raises an exception.  In general, this is important.

> However, I see that encapsulating in _one_ point the store-change-restore
> logic might be impossible here...

Yes, in a sense: try and finally are part of the same statements, but
in different "points" of the code (just like other clauses that make
up a statement, such as an if and the corresponding else).


In C++, you could use an auto variable and use its destructor for
the purpose for which here I use the restore method of the class
TweakAttributes.  In modern Python (just as in Java, etc) there is
no guarantee that a destructor runs when you'd like it to: today,
finalization should be best done explicitly with a try/finally
statement.


Alex






More information about the Python-list mailing list