Aco*_*orn 45 python variables function
是否可以获取传递给函数的变量的原始变量名?例如
foobar = "foo"
def func(var):
print var.origname
Run Code Online (Sandbox Code Playgroud)
以便:
func(foobar)
Run Code Online (Sandbox Code Playgroud)
返回:
>>foobar
编辑:
我所要做的就是做一个像下面这样的函数:
def log(soup):
f = open(varname+'.html', 'w')
print >>f, soup.prettify()
f.close()
Run Code Online (Sandbox Code Playgroud)
..并让函数从传递给它的变量的名称生成文件名.
我想如果不可能我只需要每次都将变量和变量的名称作为字符串传递.
Ivo*_*zel 55
编辑:为了说清楚,我不建议使用这个全部,它会破坏,它是一个烂摊子,它无论如何都无法帮助你,但它可以用于娱乐/教育目的.
您可以使用该inspect
模块进行攻击,我不建议这样做,但您可以这样做......
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()
Run Code Online (Sandbox Code Playgroud)
输出:
['e', '1000', 'c']
Run Code Online (Sandbox Code Playgroud)
Max*_*keh 17
你不能.它在传递给函数之前进行了评估.您所能做的就是将其作为字符串传递.
out*_*tis 10
看起来Ivo打败了我inspect
,但这是另一个实现:
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'
Run Code Online (Sandbox Code Playgroud)
当然,它可以被愚弄:
def baz():
lcl = 'hi'
x='hi'
return foo(lcl)
baz()
# 'x'
Run Code Online (Sandbox Code Playgroud)
道德:不要这样做.
pro*_*007 10
要添加到Michael Mrozek的答案中,您可以通过以下方式提取确切参数与完整代码:
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
Run Code Online (Sandbox Code Playgroud)
如果您知道调用代码的外观,您可以尝试的另一种方法是使用traceback
:
def func(var):
stack = traceback.extract_stack()
filename, lineno, function_name, code = stack[-2]
Run Code Online (Sandbox Code Playgroud)
code
将包含用于调用的代码行func
(在您的示例中,它将是字符串func(foobar)
).你可以解析它来取出参数
@Ivo Wetzel 在函数调用的情况下的答案是在一行中进行的,例如
e = 1 + 7
c = 3
foo(e, 100, b=c)
Run Code Online (Sandbox Code Playgroud)
如果函数调用不在一行中,例如:
e = 1 + 7
c = 3
foo(e,
1000,
b = c)
Run Code Online (Sandbox Code Playgroud)
下面的代码有效:
import inspect, ast
def foo(a, f, b):
frame = inspect.currentframe()
frame = inspect.getouterframes(frame)[1]
string = inspect.findsource(frame[0])[0]
nodes = ast.parse(''.join(string))
i_expr = -1
for (i, node) in enumerate(nodes.body):
if hasattr(node, 'value') and isinstance(node.value, ast.Call)
and hasattr(node.value.func, 'id') and node.value.func.id == 'foo' # Here goes name of the function:
i_expr = i
break
i_expr_next = min(i_expr + 1, len(nodes.body)-1)
lineno_start = nodes.body[i_expr].lineno
lineno_end = nodes.body[i_expr_next].lineno if i_expr_next != i_expr else len(string)
str_func_call = ''.join([i.strip() for i in string[lineno_start - 1: lineno_end]])
params = str_func_call[str_func_call.find('(') + 1:-1].split(',')
print(params)
Run Code Online (Sandbox Code Playgroud)
你会得到:
[u'e', u'1000', u'b = c']
Run Code Online (Sandbox Code Playgroud)
但是,这可能会中断。