Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从别名函数中确定函数名_Python_Python 3.x_Introspection - Fatal编程技术网

Python 从别名函数中确定函数名

Python 从别名函数中确定函数名,python,python-3.x,introspection,Python,Python 3.x,Introspection,如何确定函数是使用函数名调用的,还是通过该函数的别名调用的 通过执行以下操作,我可以检查函数以从函数体中获取其名称: import inspect def foo(): print(inspect.stack()[0][3]) foo() # prints 'foo' 资料来源: 但是,如果我对函数使用别名并尝试相同的操作,则会得到原始函数名(而不是别名) 我希望能够做到以下几点: def foo(): print(... some code goes here ...)

如何确定函数是使用函数名调用的,还是通过该函数的别名调用的

通过执行以下操作,我可以检查函数以从函数体中获取其名称:

import inspect

def foo():
   print(inspect.stack()[0][3])

foo() # prints 'foo'
资料来源:

但是,如果我对函数使用别名并尝试相同的操作,则会得到原始函数名(而不是别名)

我希望能够做到以下几点:

def foo():
    print(... some code goes here ...)

bar = foo

foo() # prints 'foo'
bar() # prints 'bar'
我有一个(有点黑)解决方案,它依赖正则表达式从字符串中解析函数名。可能有一个更干净的解决方案,但至少使用inspect only这是我能找到的最好的解决方案

import inspect
import re


function_from_call = re.compile("\w+(?=\(\))")


def foo():
    _, call_frame, *_ = inspect.stack()
    _, _, _, _, call, *_ = call_frame
    print(re.search(function_from_call, str(call)).group())

bar = foo
bar()  # prints bar
foo()  # prints foo
简要说明:首先,我抓取导致调用此函数的调用的inspect帧。然后,我从这个框架中提取实际的调用字符串,并对这个调用字符串应用一个正则表达式,它只给出函数名

注意:在解释器shell中,inspect的行为不同,上面的代码产生错误,因为我的正则表达式无法匹配实际的函数名。@user2357112在对这个问题的评论中指出了一个额外的警告:一个调用与一个名称直接关联并不明显,比如

l = [foo]; l[0]()

当从脚本运行时,我的解决方案将正确处理简单的重命名情况(如本问题中给出的情况),但我不主张使用它,因为上述情况会导致混乱的错误。

基于我对问题范围的有限了解,这是可行的:

import inspect

def foo():
  print(inspect.stack()[1][4][0].strip())

foo()
bar = foo
bar()
结果:

foo()
bar()

我真的很好奇看到这个工作!但是你的regexp对我来说不匹配,这很奇怪。您是否完全按照此处提供的方式使用了我的代码?我得到了评论的打印输出。我正在使用Python 3.5.2。以防这会影响到它。。编辑并注意:我不确定我的regexp是否可以按原样处理任意命名的函数(这就是我在上面称之为“hack”的原因)。我使用的是Python 3.6.2,inspect模块可能略有不同,当我使用inspect.stack()时,正如所料,函数名仍然是foo。我在pyenv中安装了python3.6.2,但是用它运行脚本仍然会得到我描述的输出。但是请注意,@JacobIRR的答案(它绕过了regex)使用了与我相同的inspect访问权限。不能保证用于调用函数的引用是从任何名称获得的。它可能是
l=[foo];l[0]()
排序(一些列表,key=l[0])
。这是一个好的观点,我想在这种情况下
l[0]()
应该打印
l[0]
。这对我来说会引发一个“非类型不可订阅”错误。我可以改为使用inspect.stack()[0][3]使其工作,但它仍然返回'foo'。你知道如何才能真正做到这一点吗?它在解释器中不起作用,但作为脚本起作用。谢谢,这对我来说很有用(在解释器中以及在python3.6的脚本中),并且还有另外一个好处,就是在括号中给出参数。@OlivierMelançon,恶心。。看来解决这个问题的任何方法都是很难的。我唯一能想到的另一件事是循环遍历堆栈的所有部分,如果函数名不是原始名称,但仍然是hack@JacobIRR事实上,我真的很惊讶,你能让它像现在这样工作,干得好!
foo()
bar()