Binding a reference to a variable (solved?!?)

Patrick Miller patmiller at llnl.gov
Wed Apr 10 14:21:59 EDT 2002


Here's a scary way to do what Andrew was looking for.  It has
the proper form and fewer (but still significant) restrictions.

>>> x = 7
>>> set(x,99)
>>> print x

I'll likely submit the following as a ASPN recipe, though
it clearly needs a better description of motivation.  Just
because you CAN do a thing doesn't mean you SHOULD
do a thing.

#**************************************************************************#
#* FILE   **************        globally.py        ************************#
#**************************************************************************#
#* Author: Patrick Miller April 10 2002                                   *#
#**************************************************************************#
#* Real hack to allow update of global variables by value, not name       
#*
#* The ''set'' function needs a dictionary within which to look for values
#* (defaults to the current global scope).  The ''setAnywhere'' function
#* looks in all the global module scopes.
#*        
#* Note that this only works for items with unique identifiers.
#* For instance, small integers 'a = 3; b = 3' have shared python
#* objects (id(a) == id(b)).  The method works OK for lists
#* and dictionaries and the like because python creates a new unique
#* address for each instance (unlike int's which look to share)
#**************************************************************************#

x = 3
y = [1,2,3,4,]
z = {"something": 0}


def set(lhs,rhs,G=globals()):
    address = id(lhs)
    identifiers = map(lambda x: id(x), G.values())
    try:
        index = identifiers.index(address)
    except ValueError:
        raise ValueError,lhs
    label = G.keys()[index]
    G[label] = rhs
    return rhs

def setAnywhere(lhs,rhs):
    import sys
    for module in sys.modules.values():
        try:
            dict = module.__dict__
            try:
                set(lhs,rhs,module.__dict__)
                break
            except ValueError:
                pass
        except:
            pass
    else:
        raise ValueError,lhs
    return rhs

print
print 'before',repr(x),repr(y),repr(z)
set(x,99)
set(y,'something new')
set(z,42)
print 'after',repr(x),repr(y),repr(z)

import math
print 'math.pi',math.pi
setAnywhere(math.pi,3) # see http://www.snopes2.com/religion/pi.htm
print 'math.pi',math.pi
        

-- 
Patrick Miller | (925) 423-0309 | patmiller at llnl.gov

Adults are obsolete children.
-- Dr. Seuss, humorist, illustrator, and author (1904-1991)





More information about the Python-list mailing list