gpt4 book ai didi

python - 为什么 locals() 会返回一个奇怪的自引用列表?

转载 作者:太空狗 更新时间:2023-10-29 17:14:02 26 4
gpt4 key购买 nike

所以我使用 locals() 来获取函数中的一些参数。效果很好:

def my_function(a, b):
print locals().values()

>>> my_function(1,2)
[1, 2]

标准的东西。但是现在让我们介绍一个列表理解:

def my_function(a, b):
print [x for x in locals().values()]

>>> my_function(1,2)
[[...], 1, 2]

嗯?为什么要插入自引用?

最佳答案

2.7 和 3.1 之前的 Python 版本使用次优字节码来生成列表理解。在那些 Python 版本中,列表理解存储在局部变量中(如果在模块范围内,甚至是全局变量):

>>> import dis
>>> def foo():
... return [x for x in y]
...
>>> dis.dis(foo)
2 0 BUILD_LIST 0
3 DUP_TOP
4 STORE_FAST 0 (_[1])
7 LOAD_GLOBAL 0 (y)
10 GET_ITER
>> 11 FOR_ITER 13 (to 27)
14 STORE_FAST 1 (x)
17 LOAD_FAST 0 (_[1])
20 LOAD_FAST 1 (x)
23 LIST_APPEND
24 JUMP_ABSOLUTE 11
>> 27 DELETE_FAST 0 (_[1])
30 RETURN_VALUE

_[1] 局部变量是正在进行的列表。当嵌套列表理解时,它会使用递增的整数来引用结果:

>>> def bar():
... return [[x for x in y] for z in spam]
...
>>> dis.dis(bar)
2 0 BUILD_LIST 0
3 DUP_TOP
4 STORE_FAST 0 (_[1])
7 LOAD_GLOBAL 0 (spam)
10 GET_ITER
>> 11 FOR_ITER 40 (to 54)
14 STORE_FAST 1 (z)
17 LOAD_FAST 0 (_[1])
20 BUILD_LIST 0
23 DUP_TOP
24 STORE_FAST 2 (_[2])
27 LOAD_GLOBAL 1 (y)
30 GET_ITER
>> 31 FOR_ITER 13 (to 47)
34 STORE_FAST 3 (x)
37 LOAD_FAST 2 (_[2])
40 LOAD_FAST 3 (x)
43 LIST_APPEND
44 JUMP_ABSOLUTE 31
>> 47 DELETE_FAST 2 (_[2])
50 LIST_APPEND
51 JUMP_ABSOLUTE 11
>> 54 DELETE_FAST 0 (_[1])
57 RETURN_VALUE

通过遍历 locals().values(),您在返回值中包含了对进行中列表的引用。请注意,字节码使用 DELETE_FAST 来清理本地名称以尝试避免命名空间污染。

这针对 Python 3.1 和 2.7 进行了优化,请参阅 issue 2183 .正在构建的列表结果被移到了堆栈中。优化更改了 LIST_APPEND 字节码以引用堆栈上要追加的列表,从而无需在开始时使用 DUP_TOP -> STORE_FAST , LOAD_FAST 每次迭代和 DELETE_FAST 在列表推导之后。

关于python - 为什么 locals() 会返回一个奇怪的自引用列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22307520/

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