Scoped change of a global variable

Luigi Ballabio ballabio at mac.com
Wed Jan 2 06:29:45 EST 2002


Greetings everybody,
	the statement of the case: let's say I have a function which adds two 
numbers and returns their sum rounded with a precision which is not passed 
as a parameter but rather stored in a global variable, as in:

precision = 2

def add(x,y):
     sum = x+y
     tens = math.pow(10.0,precision)
     return math.floor(sum*tens+0.5)/tens

Now let's say that I want to call add with a different precision but I 
politely want to restore the previous value after I'm done. What I do is:

oldPrecision = precision    # store old value
precision = 3               # change current value
x = add(1.0,0.3456)         # do the deed
precision = oldPrecision    # restore old value

The question is: how can I encapsulate the logic in the comments above?

For example, in Scheme I can define a macro with-precision so that writing:

(with-precision 3
   (set! x (add 1.0 0.3456)))

sets x to 1.346 and restores the precision to its old value.

In Ruby, I can define a function withPrecision so that writing:

withPrecision(1) {
     x = add(1.0,0.3456)
}

sets x to 1.3 etc. etc.

Now, what about Python? One could write

def withPrecision(newPrecision,block):
     global precision
     oldPrecision = precision
     precision = newPrecision
     result = block()
     precision = oldPrecision
     return result

However, the problem is that even the simple assignment above requires one 
to define a function since it can't be done inside a lambda. Thus, the 
simple Scheme or Ruby idiom becomes as crufty as:

def doIt():
     global x
     x = add(1.0,0.3456)

withPrecision(1,doIt)

which does the trick but isn't as concise and expressive (not to mention 
elegance and lack of clarity if the above has to be done in the middle of a 
longer block of code).

Any ideas?

Thanks,
		Luigi

P.S. the name of the game here is encapsulating the 
store-set-calculate-restore logic; it is not to show me that there are 
better ways to implement the above than to access a global variable. I 
know. The above is just a contrived 10 lines example to show my point.





More information about the Python-list mailing list