How safe is modifying locals()?

Shane Hathaway shane at zope.com
Fri Jul 25 18:19:48 EDT 2003


Paul Paterson wrote:
> I am trying to find a way to mimic by-reference argument passing for 
> immutables in Python. I need to do this because I am writing an 
> automated VB to Python converter.
> 
> Here's an example of the VB code:
> 
> Sub Change(ByVal x, ByRef y)
> x = x+1
> y = y+1
> End Sub
> 
> x = 0: y = 0
> Change x, y
> ' Now x should be 0 and y should be 1

I might put all of the "ByRef" variables in a dictionary that gets 
passed back to the caller through a hidden argument.

def change(x, y, _byref):
   x = x + 1
   y = _byref['y'] = y + 1

x = 0; y = 0
__byref = {'y': y}; change(x, y, __byref); y = __byref['y']

At least this relies on nothing magical.  One thing that's still wrong, 
though, is that you can't embed the change() call in an expression. 
AFAIK, in Python, assignment to a local variable absolutely requires a 
statement.  You can get around this by splitting apart the expression 
and storing the result of the call in another hidden temporary variable.

Even if you do that, though, exceptions will behave differently in 
Python than they do in VB.  If an exception occurs in change() after a 
value has been assigned to 'y', the outer code won't get the value, and 
it just might affect the behavior of the outer code.  You could fix that 
with a try: / finally:

__byref = {'y': y}
try:
   change(x, y, __byref)
finally:
   y = __byref['y']

Suddenly it's awfully verbose and ugly, but if variables by reference 
are rare (as they should be), maybe it's not so bad. :-)

You could go the extreme route and store all variables in dictionaries 
rather than use local variables, which would allow "true" references, 
but then you'd kill speed and readability.  Better not do that.

Shane






More information about the Python-list mailing list