Tuesday, April 05, 2005

A pass by reference decorator

#passbyref.py
#
#Implementing pass by reference operations
#in python.
#
#Exanple
#python passbyref.py
#>>>@passbyreference(sym.b)
#...def func(a):
#...    a.set("hello")
#>>>
#>>>v = 5
#>>>func(1, sym.v, 3)
#>>>print v
#hello
#

import inspect

class _symbol(object):
    def __getattribute__(self, name):
        return name
sym = _symbol()


class ref:
    def __init__(self, value):
        self.value = value
    
    def set(self, value):
        self.value = value

    def get(self):
        return self.value
    
    def __repl__(self):
        return "ref(%s)" % self.value

    def __str__(self):
        return self.value
    
 
def passbyreference(*refparams):
    def getfunc(func):
        fc = func.func_code
        paramcount = fc.co_argcount
        paramnames = list(fc.co_varnames[:paramcount])
        def pbr(*args, **aargs):
            callerLocals = inspect.currentframe(1).f_locals
            callerRefVars = []
            argsMap = {}
            argsMap.update(dict(zip(paramnames[:len(args)], args)))
            argsMap.update(aargs)
            for paramName in refparams:
                varName = argsMap[paramName]
                varRef = ref(callerLocals[varName])
                argsMap[paramName] = varRef
                callerRefVars.append((varName, varRef))
            
            retval = func(**argsMap)

            for varName, varRef in callerRefVars:
                callerLocals[varName] = varRef.get()
            return retval
        return pbr
    return getfunc

2 Comments:

At 10:45 PM, Anonymous Anonymous said...

A simpler solution would be

def func((v)):
v = "hello"

a=(5)
func(a)
print a[0] #shows hello

 
At 11:12 PM, Blogger monkeeboi said...

I guess what you are trying to do is this

def func(v):
  v[0] = "hello"

a = [None]

func(a)
print a[0] # now prints hello

It should be noted that tuples are immutable.

Also a = (5) is the same as a = 5 to get a tuple containing a single element you should write a = (5,).

 

Post a Comment

<< Home