我可以知道函数是直接调用还是通过分配的变量

时间:2019-01-21 15:47:03

标签: python python-2.7

假设我有一个函数def f(): print 0,并且我想创建另一个函数g,但是g的实现与f相同,因此我只分配{{ 1}}:

f

您可能会问,如果它们相同,为什么要使用2个函数,这是因为从逻辑上讲,它们代表2个不同的事物

现在,我能知道谁叫吗?我只想在通过def f(): print 0 g = f 调用f()时调试它。这两个呼叫之间的流量是否不同?

dup建议与我的问题无关。我知道该函数的名称,因为只有一个函数存在。我只是希望更进一步,了解是否触发了一个与函数名称具有相同值的变量...

4 个答案:

答案 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了-您只需要检查调用堆栈即可。