如何将当前函数转换为变量?

发布于 2021-01-29 19:34:53

如何获取包含Python中当前正在执行的函数的变量?我不需要函数的名称。我知道我可以inspect.stack用来获取当前的函数名称。我想要实际的可调用对象。是否可以不使用inspect.stack检索函数名称,然后eval输入名称以获取可调用对象而完成此操作?

编辑:
我有这样做的理由,但它甚至不是一个很好的选择。我正在使用plac解析命令行参数。您可以通过使用来使用它plac.call(main),它会根据“
main”的函数签名生成一个ArgumentParser对象。在“
main”内部,如果参数存在问题,我想退出并显示一条错误消息,其中包含ArgumentParser对象的帮助文本,这意味着我需要通过调用直接访问此对象plac.parser_from(main).print_help()。可以这样说::plac.parser_from(get_current_function()).print_help(),这样我就不必依赖被命名为“
main”的函数了。现在,我对“ get_current_function”的实现是:

import inspect    
def get_current_function():
    return eval(inspect.stack()[1][3])

但是此实现依赖于具有名称的功能,我想这个名称不太繁琐。我永远不会做plac.call(lambda ...)

从长远来看,让plac的作者实现print_help方法来打印最近使用plac或类似方法调用的函数的帮助文本可能会更有用。

关注者
0
被浏览
75
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    堆栈框架告诉我们我们位于哪个代码对象中。如果我们可以找到在其__code__属性中引用该代码对象的功能对象,那么我们已经找到了该功能。

    幸运的是,我们可以询问垃圾回收器,哪些对象持有对我们代码对象的引用,并对其进行筛选,而不必遍历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 type(func) is functype:
                if getattr(func, "__code__", None) is code:
                    if getattr(func, "__globals__", None) is globs:
                        funcs.append(func)
                        if len(funcs) > 1:
                            return None
        return funcs[0] if funcs else None
    

    一些测试用例:

    def foo():
        return giveupthefunc()
    
    zed = lambda: giveupthefunc()
    
    bar, foo = foo, None
    
    print bar()
    print zed()
    

    我不确定这个的性能特征,但是我认为这对您的用例来说应该没问题。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看