如何在Python中获取嵌套函数的命名空间?

时间:2014-07-16 02:45:46

标签: python

我有这段代码:

def make_caller(fn):
    def inner():
        fn()
    return inner

def random_function_1(): pass
def random_function_2(): return 42
def random_function_3(): return 69

callers = [
    make_caller(random_function_1),
    make_caller(random_function_2),
    make_caller(random_function_3),
]

现在callers中的所有功能都被称为inner

>>> [x.__name__ for x in callers]
['inner', 'inner', 'inner']

使用callers,我该如何获得random_function_1random_function_2random_function_3

2 个答案:

答案 0 :(得分:2)

  

使用来电者,我如何获得random_function_1,random_function_2,   和random_function_3?

可以使用 __ closure __ 属性访问它们:

>>> [caller.__closure__[0].cell_contents for caller in callers]
[<function random_function_1 at 0x1004e0de8>, <function random_function_2 at 0x1004e0e60>, <function random_function_3 at 0x103b70de8>]

__ closure __ 属性记录在https://docs.python.org/2.7/reference/datamodel.html?highlight=closure#the-standard-type-hierarchy的可调用类型部分

答案 1 :(得分:1)

你可以作弊并这样做:

>>> callers[0].func_closure[0].cell_contents.__name__
'random_function_1'

但是,如果函数更复杂(包含的自由变量多于fn),则必须将其与callers[0].func_code.co_freevars相关联。此外,直接摆弄这样的闭包对象是一个可疑的业务。最终,inner抛弃了有关它所包含的函数名称的信息;你只能通过这种作弊来取回它。如果make_caller希望其他人能够知道包装函数的名称,那么它应该明确地提供该信息。