所以我使用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]
EHH?为什么要插入自引用?
答案 0 :(得分:25)
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
。