Gathering variable names from within a function.

Sean Ross frobozz_electric at hotmail.com
Mon Jul 7 11:06:31 EDT 2003


This will seem excessive, but it`s a little hack I`ve been playing with.
WARNING: It`s incomplete, and, in general,  it should probably *not* be
used. Still, here it is, if you`re interested:

import inspect

class ThisResolutionError(Exception):
    pass

def this():
    "returns the function object that calls it"
    # get calling function's name from outer frame
    fname = inspect.currentframe(1).f_code.co_name
    frameno = 2
    func = None
    while func is None:
        # search the outer frames for a reference to this function
        try:
            func = inspect.currentframe(frameno).f_locals.get(fname, None)
            frameno += 1
        except ValueError:
            # reached end of call stack
            raise ThisResolutionError, "could not resolve %s"%fname
    return func  # return this function object

'this()' can be used to get hold of the function that you're currently in;
you may then manipulate or inspect that function as you please.

for example:

def modvars(arg1, arg2):
    "records it's own modified variables"
    var1 = arg1
    var2 = arg2
    var3 = arg1+arg2
    this().__dict__ = vars()
    print this().__doc__
    return var3

modvars(1,2)
print modvars.__dict__

# OUTPUT:
# records it's own modified variables
# {'arg1': 1, 'arg2': 2, 'var1': 1, 'var3': 3, 'var2': 2}


'this()' appears to work for functions, including nested functions, but it
does not work for bound/unbound methods, or functions stored in a dictionary
(yet). For instance, you can do the following:

def f():
    def g():
        print "g says 'Hello'"
    this().g = g
print f.g
print f.g()
# <function g at 0x00958C60>
# g says 'Hello'

But you can't do this:

def f():
    def g():
        "g says 'Hello'"
        print this().__doc__
    this().g = g
print f.g()
# ThisResolutionError: could not resolve g

Anyway, it's still pretty neat to be able to grab hold of a function, from
inside itself, and work with it.
Sean






More information about the Python-list mailing list