假设我有一个函数def f(): print 0
,并且我想创建另一个函数g
,但是g
的实现与f
相同,因此我只分配{{ 1}}:
f
您可能会问,如果它们相同,为什么要使用2个函数,这是因为从逻辑上讲,它们代表2个不同的事物
现在,我能知道谁叫吗?我只想在通过def f():
print 0
g = f
调用f()
时调试它。这两个呼叫之间的流量是否不同?
dup建议与我的问题无关。我知道该函数的名称,因为只有一个函数存在。我只是希望更进一步,了解是否触发了一个与函数名称具有相同值的变量...
答案 0 :(得分:2)
不,您不能(至少不能这样),因为Python不会跟踪“查找到该对象的引用”。我强烈建议您使g
成为另一个封装f
的函数,以减少痛苦的调试体验。
但是,如果您的代码遵循某些模式,则可以通过查看inspect.stack()
:
import inspect
def f():
stack = inspect.stack()
print(stack[1].code_context[0].strip())
g = f
f()
g()
幸运的是,您会得到
f()
g()
如果您具有一些正则表达式技能,则可以使用以下方法之一提取函数名称:
import re
func_name_re = re.compile(r"\b(\w+)\s*\()")
line = "f()"
print(func_name_re.search(line).group(1))
但是,如果您的调用代码边际变得更加复杂,您将很容易遇到识别真实函数的麻烦:
some = f(g())
some[f()] = g()
some = f("aaa g() sss") # string content looks like function call
some = re.compile(r"^f(?!$)", flags=g()) # same as above
在上述所有示例中,您很难确定是f
还是g
。
答案 1 :(得分:1)
这行不通。
输入:
def f():
pass
g = f
print(f.__name__)
print(g.__name__)
print(id(f))
print(id(g))
输出:
f
f
4350036880
4350036880
我只能想到的解决方法是在调用eval的函数周围创建某种类型的包装器,并以这种方式处理(但很可能对于您想做的事情没有意义)。然后,您可以使用func_name参数调用该包装器。
func_name = 'f'
if func_name =='f':
## you know f was called
eval('f()')
答案 2 :(得分:0)
没有附加的助手或代码分析是不可能的。
即使堆栈也不知道被调用的名称:
>>> def a(): traceback.print_stack()
...
>>> b = a
>>> a()
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in a
>>> b()
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in a
>>>
答案 3 :(得分:0)
我可以建议最简单的解决方案吗?
def f():
print 0
def g():
return f()
现在,您清楚地知道何时通过f
调用g
了-您只需要检查调用堆栈即可。