How to get the original variable name of variable passed to a function

EDIT: To make it clear, I don't recommend using this AT ALL, it will break, it's a mess, it won't help you in any way, but it's doable for entertainment/education purposes.

You can hack around with the inspect module, I don't recommend that, but you can do it...

import inspect

def foo(a, f, b):
    frame = inspect.currentframe()
    frame = inspect.getouterframes(frame)[1]
    string = inspect.getframeinfo(frame[0]).code_context[0].strip()
    args = string[string.find('(') + 1:-1].split(',')
    
    names = []
    for i in args:
        if i.find('=') != -1:
            names.append(i.split('=')[1].strip())
        
        else:
            names.append(i)
    
    print names

def main():
    e = 1
    c = 2
    foo(e, 1000, b = c)

main()

Output:

['e', '1000', 'c']

You can't. It's evaluated before being passed to the function. All you can do is pass it as a string.


To add to Michael Mrozek's answer, you can extract the exact parameters versus the full code by:

import re
import traceback

def func(var):
    stack = traceback.extract_stack()
    filename, lineno, function_name, code = stack[-2]
    vars_name = re.compile(r'\((.*?)\).*$').search(code).groups()[0]
    print vars_name
    return

foobar = "foo"

func(foobar)

# PRINTS: foobar

Looks like Ivo beat me to inspect, but here's another implementation:

import inspect

def varName(var):
    lcls = inspect.stack()[2][0].f_locals
    for name in lcls:
        if id(var) == id(lcls[name]):
            return name
    return None

def foo(x=None):
    lcl='not me'
    return varName(x)

def bar():
    lcl = 'hi'
    return foo(lcl)

bar()
# 'lcl'

Of course, it can be fooled:

def baz():
    lcl = 'hi'
    x='hi'
    return foo(lcl)

baz()
# 'x'

Moral: don't do it.


Another way you can try if you know what the calling code will look like is to use traceback:

def func(var):
    stack = traceback.extract_stack()
    filename, lineno, function_name, code = stack[-2]

code will contain the line of code that was used to call func (in your example, it would be the string func(foobar)). You can parse that to pull out the argument