看看这个:
>>> def f():
... return (2+3)*4
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
显然,编译器已经预先评估了(2+3)*4
,这是有道理的。
现在,如果我只是改变*
:
>>> def f():
... return 4*(2+3)
...
>>> dis(f)
2 0 LOAD_CONST 1 (4)
3 LOAD_CONST 4 (5)
6 BINARY_MULTIPLY
7 RETURN_VALUE
表达式不再完全预先评估!这是什么原因?我正在使用CPython 2.7.3。
答案 0 :(得分:9)
在第一种情况下,未经优化的代码为LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY
,在第二种情况下为LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLY
。 fold_binops_on_constants()
中的模式匹配器必须处理第一个ADD
确定(用LOAD LOAD ADD
替换LOAD
),然后继续对MULTIPLY
执行相同的操作。在第二种情况下,当ADD
(现在是MULTIPLY
的第二个参数而不是第一个参数)变为常量时,扫描程序太远而无法查看L L M
(当“光标”在LOAD 4
上,它看起来不像L L M
。
答案 1 :(得分:5)
看起来这个问题已在Python 3.3中修补,可以看作here。
>>> def f():
... return (2+3)*4
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE
>>> def f():
... return 4*(2+3)
...
>>> dis(f)
2 0 LOAD_CONST 5 (20)
3 RETURN_VALUE