Python代码获取当前函数到一个变量? [英] Python code to get current function into a variable?
问题描述
如何获得包含Python中当前正在执行的函数的变量?我不想要这个函数的名字。我知道我可以使用 inspect.stack
来获取当前的函数名称。我想要实际的可调用对象。可以在不使用 inspect.stack
来检索函数的名称,然后使用 eval
名称来获得可调用对象?
编辑:我有理由这样做,但它甚至不是一个好的。我使用 plac 来解析命令行参数。通过执行 plac.call(main)
来使用它,它从main的函数签名中生成一个ArgumentParser对象。在main里面,如果参数有问题,我想退出时会出现一条错误消息,其中包含来自ArgumentParser对象的帮助文本,这意味着我需要通过调用直接访问此对象。 plac.parser_from(主).print_help()
。我们可以这样说: plac.parser_from(get_current_function())。print_help()
,这样我就不依赖于名为main 。现在,我的get_current_function的实现将是:
pre code import import inspect
def get_current_function():
return eval(inspect.stack()[1] [3])
但是这个实现依赖于这个函数有一个名字,我想这不是太繁重。我永远不会做 plac.call(lambda ...)
。
从长远来看,让plac的作者实现print_help方法来打印最近使用plac调用的函数的帮助文本或类似的东西可能更有用。
幸运的是,我们可以向垃圾收集器询问哪些对象持有对我们的代码对象的引用,并筛选出这些对象,而不必遍历Python世界中的每个活动对象。通常只有少数几个对代码对象的引用。
现在,函数可以共享代码对象,并且可以在返回函数的情况下一个函数,即一个闭包。当有多个函数使用给定的代码对象时,我们无法知道它是哪个函数,所以我们返回 None
。
import inspect,gc
def giveupthefunc():
frame = inspect.currentframe(1)
code = frame .f_code
globs = frame.f_globals
functype = type(lambda:0)
funcs = []
for func in gc.get_referrers(code):
if如果getattr(func,func_code,None)为代码:
(func,func_globals,None)为globs:
funcs.append (func)
len(funcs)> 1:
返回无
返回funcs [0] if funcs else无
一些测试用例:
def foo():
return giveupthefunc()
zed = lambda:giveupthefunc()
bar,foo = foo,None
print bar()
print zed()
我不确定这个的性能特征,但我认为它应该适用于您的用例。
How can I get a variable that contains the currently executing function in Python? I don't want the function's name. I know I can use inspect.stack
to get the current function name. I want the actual callable object. Can this be done without using inspect.stack
to retrieve the function's name and then eval
ing the name to get the callable object?
Edit: I have a reason to do this, but it's not even a remotely good one. I'm using plac to parse command-line arguments. You use it by doing plac.call(main)
, which generates an ArgumentParser object from the function signature of "main". Inside "main", if there is a problem with the arguments, I want to exit with an error message that includes the help text from the ArgumentParser object, which means that I need to directly access this object by calling plac.parser_from(main).print_help()
. It would be nice to be able to say instead: plac.parser_from(get_current_function()).print_help()
, so that I am not relying on the function being named "main". Right now, my implementation of "get_current_function" would be:
import inspect
def get_current_function():
return eval(inspect.stack()[1][3])
But this implementation relies on the function having a name, which I suppose is not too onerous. I'm never going to do plac.call(lambda ...)
.
In the long run, it might be more useful to ask the author of plac to implement a print_help method to print the help text of the function that was most-recently called using plac, or something similar.
The stack frame tells us what code object we're in. If we can find a function object that refers to that code object in its func_code
attribute, we have found the function.
Fortunately, we can ask the garbage collector which objects hold a reference to our code object, and sift through those, rather than having to traverse every active object in the Python world. There are typically only a handful of references to a code object.
Now, functions can share code objects, and do in the case where you return a function from a function, i.e. a closure. When there's more than one function using a given code object, we can't tell which function it is, so we return None
.
import inspect, gc
def giveupthefunc():
frame = inspect.currentframe(1)
code = frame.f_code
globs = frame.f_globals
functype = type(lambda: 0)
funcs = []
for func in gc.get_referrers(code):
if type(func) is functype:
if getattr(func, "func_code", None) is code:
if getattr(func, "func_globals", None) is globs:
funcs.append(func)
if len(funcs) > 1:
return None
return funcs[0] if funcs else None
Some test cases:
def foo():
return giveupthefunc()
zed = lambda: giveupthefunc()
bar, foo = foo, None
print bar()
print zed()
I'm not sure about the performance characteristics of this, but i think it should be fine for your use case.
这篇关于Python代码获取当前函数到一个变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!