我有这段代码:
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_1
,random_function_2
和random_function_3
?
答案 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
希望其他人能够知道包装函数的名称,那么它应该明确地提供该信息。