为什么这两个功能不同?

时间:2013-07-23 01:11:26

标签: python python-2.7 bytecode cpython

看看这个:

>>> 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。

2 个答案:

答案 0 :(得分:9)

在第一种情况下,未经优化的代码为LOAD 2 LOAD 3 ADD LOAD 4 MULTIPLY,在第二种情况下为LOAD 4 LOAD 2 LOAD 3 ADD MULTIPLYfold_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