Python 获取闭包的父函数

Python 获取闭包的父函数,python,closures,Python,Closures,从internal\u func或bar获取对父函数foo的引用是否可能 查看PythonTutorOnline的源代码,我找到了我需要的。有没有其他方法可以做到这一点?如果没有,我如何在不使用Bdb的情况下获取当前堆栈信息?这只会在另一个函数的主体中找到FunctionDef: test.py: 代码: 输出: import ast def find_parent(par): for par_node in mod.body: if isinstance(par_n

internal\u func
bar
获取对父函数
foo
的引用是否可能


查看
PythonTutorOnline
的源代码,我找到了我需要的。有没有其他方法可以做到这一点?如果没有,我如何在不使用
Bdb
的情况下获取当前堆栈信息?

这只会在另一个函数的主体中找到FunctionDef:

test.py:

代码:

输出:

import ast


def find_parent(par):
    for par_node in mod.body:
        if isinstance(par_node, ast.FunctionDef):
            for node in par_node.body:
                if isinstance(node, ast.FunctionDef) and node.name == inner_func.func_name:     
                    return eval(par_node.name)
n[12]:来自测试导入*
在[13]中:mod=ast.parse(open(“/home/padraic/test.py”).read())
在[14]中:查找父项(mod)
出[14]:
在[15]中:查找父项(mod).func\u名称
Out[15]:“foo”

这远非完美,但有一个想法:

getattr(\uuuuu import\uuuuuuuu(foo().\uuuuuu module\uuuuuuuuuuuu),'foo')


根据@zondo的评论,可以以某种方式获得名称
'foo'

我认为可能会有所帮助。在
栏中尝试
inspect.stack()
。(我不太确定tho)@BhargavRao:我刚刚测试了它,你可以得到
foo()
,但你不能得到实际的函数对象。@zondo你如何获得名称?我发布了一个基于此的答案。@AlexHall:
inspect.stack()[0]
是调用
inspect.stack()
的级别,因此
inspect.stack()[1]
是上一个级别:在
foo()中调用
bar()
。该列表是帧、文件、行号、函数、实际代码文本以及其他一些看起来总是为零的数字。因此,要获取名称,请在
bar()的内部使用
inspect.stack()[1][3]
。这将得到名称
foo
,因为它是从
bar()
向上的,但是如果您想要它,因为它比模块低一级,请使用
inspect.stack()[-2][3]
@BhargavRao,这涉及到更改函数和调用内部函数,我不确定这是需要的。如果以前有一个函数定义为与闭包相同的名称,它就无法说出
AttributeError:“NoneType”对象没有属性“name”
@AdnanUmer,这是我回答的第一行,您是否愿意使用调用internal_func来获取父对象?不,这只是一个示例。在现实中,这可以是任何闭包,我必须弄清楚它实际上是在哪里定义的。@AdnanUmer,你说的弄清楚它是在哪里定义的是什么意思?你到底想用它做什么?这已经足够好了,但我只是觉得每次我尝试得到父函数时,我会得到一个不同的对象。
def bar():
    pass

def foo():
    def bar():
        pass
    return bar

inner_func = foo()
import ast


def find_parent(par):
    for par_node in mod.body:
        if isinstance(par_node, ast.FunctionDef):
            for node in par_node.body:
                if isinstance(node, ast.FunctionDef) and node.name == inner_func.func_name:     
                    return eval(par_node.name)
n [12]: from test import  *

In [13]: mod =  ast.parse(open("/home/padraic/test.py").read())

In [14]: find_parent(mod)
Out[14]: <function test.foo>

In [15]: find_parent(mod).func_name
Out[15]: 'foo'