How to get the original variable name of variable

2019-01-03 03:24发布

Is it possible to get the original variable name of a variable passed to a function? E.g.

foobar = "foo"

def func(var):
    print var.origname

So that:

func(foobar)

Returns:

>>foobar

EDIT:

All I was trying to do was make a function like:

def log(soup):
    f = open(varname+'.html', 'w')
    print >>f, soup.prettify()
    f.close()

.. and have the function generate the filename from the name of the variable passed to it.

I suppose if it's not possible I'll just have to pass the variable and the variable's name as a string each time.

7条回答
家丑人穷心不美
2楼-- · 2019-01-03 03:40

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 anyway, 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']
查看更多
神经病院院长
3楼-- · 2019-01-03 03:46

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

查看更多
Deceive 欺骗
4楼-- · 2019-01-03 03:48

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.

查看更多
劳资没心,怎么记你
5楼-- · 2019-01-03 03:50

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
查看更多
霸刀☆藐视天下
6楼-- · 2019-01-03 03:54

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

查看更多
爷、活的狠高调
7楼-- · 2019-01-03 04:00

If you want a Key Value Pair relationship, maybe using a Dictionary would be better?

...or if you're trying to create some auto-documentation from your code, perhaps something like Doxygen (http://www.stack.nl/~dimitri/doxygen/) could do the job for you?

查看更多
登录 后发表回答