gpt4 book ai didi

python - 如何将 func_closure 条目映射到变量名?

转载 作者:太空狗 更新时间:2023-10-29 21:18:38 25 4
gpt4 key购买 nike

我有一个在此函数中创建的 lambda 对象:

def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
self.record(lambda s:
s.add_url_rule(rule, endpoint, view_func, **options))

使用 lambda 函数对象的 func_closure 我可以访问 lambda 函数的闭包范围:

(<cell at 0x3eb89f0: str object at 0x2fb4378>,
<cell at 0x3eb8a28: function object at 0x3cb3a28>,
<cell at 0x3eb8a60: str object at 0x3ebd090>,
<cell at 0x3eb8b08: dict object at 0x3016ec0>)

仔细观察(每个 cell 对象的 cell_contents 属性)显示:

>>> [c.cell_contents for c in func.func_closure]
['categoryDisplay',
<function indico.web.flask.util.RHCategoryDisplay>,
'/<categId>/',
{}]

该 lambda 函数是通过以下调用创建的:

add_url_rule('/<categId>/', 'categoryDisplay', rh_as_view(RHCategoryDisplay))

如您所见,该顺序与函数的参数顺序或参数在 lambda 中的使用顺序不匹配。虽然我可以根据其类型/内容轻松找出哪个元素是什么,但我想以一种更简洁的方式进行。

所以我的问题是:如何将它与它们的原始变量名(或者至少是函数参数的位置)相关联?

最佳答案

闭包由 LOAD_CLOSURE 字节码创建,其顺序与其字节码的顺序相同:

>>> dis.dis(add_url_rule)
2 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (record)
6 LOAD_CLOSURE 0 (endpoint)
9 LOAD_CLOSURE 1 (options)
12 LOAD_CLOSURE 2 (rule)
15 LOAD_CLOSURE 3 (view_func)
18 BUILD_TUPLE 4
21 LOAD_CONST 1 (<code object <lambda> at 0x10faec530, file "<stdin>", line 2>)
24 MAKE_CLOSURE 0
27 CALL_FUNCTION 1
30 POP_TOP
31 LOAD_CONST 0 (None)
34 RETURN_VALUE

所以顺序是在编译时确定的,由compiler_make_closure() ;此函数使用 func.func_code.co_freevars 元组作为指南,它以相同的顺序列出闭包。

func.func_code.co_freevarsmakecode 中创建代码对象时设置,并且元组是从 python 字典的键生成的,因此顺序是任意的,这对于字典来说很常见。如果你好奇的话,dict 是内置在 compiler_enter_scope() 中的。 , 使用 dictbytype() utility function来自编译器符号表中命名的所有自由变量,它本身就是一个 Python 字典。

因此,闭包的顺序确实是任意的(哈希表有序),您可以使用 func.func_code.co_freevars 元组(可以看作是闭包顺序的记录)编译器处理字典键)以将名称附加到闭包:

dict(zip(func.func_code.co_freevars, (c.cell_contents for c in func.func_closure)))

关于python - 如何将 func_closure 条目映射到变量名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17145260/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com