这个计算是在Python中执行的吗?

Is this calculation executed in Python?

Disclaimer: I'm new to programming, but new to Python. This may be a pretty basic question.

我有以下代码块:

for x in range(0, 100):
    y = 1 + 1;

第二行1 + 1的计算是否执行了100次?

我有两个怀疑为什么不能:

1) 编译器将1 + 1视为常量值,因此将这一行编译成y = 2;.

2) 编译器看到y只被设置而没有被引用,所以省略了这行代码。

这些 either/both 是否正确,或者它实际上在循环中的每次迭代中都执行了吗?

选项1被执行; CPython 编译器在窥视孔优化器中使用常量简化了数学表达式。

Python 但是不会消除循环体。

您可以通过查看字节码来反省 Python 产生的内容;用dis module看一下:

>>> import dis
>>> def f():
...     for x in range(100):
...         y = 1 + 1
... 
>>> dis.dis(f)
  2           0 SETUP_LOOP              26 (to 29)
              3 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (100)
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             12 GET_ITER
        >>   13 FOR_ITER                12 (to 28)
             16 STORE_FAST               0 (x)

  3          19 LOAD_CONST               3 (2)
             22 STORE_FAST               1 (y)
             25 JUMP_ABSOLUTE           13
        >>   28 POP_BLOCK
        >>   29 LOAD_CONST               0 (None)
             32 RETURN_VALUE

位置19的字节码,LOAD_CONST加载值2存储在y.

代码对象的co_consts属性中可以看到代码对象关联的常量;对于函数,您可以在 __code__ 属性下找到该对象:

>>> f.__code__.co_consts
(None, 100, 1, 2)

None 是任何函数的默认 return 值,100 传递给 range() 调用的文字,1 原始文字,左侧由窥视孔优化器放置,2 是优化的结果。

工作在peephole.c, in the fold_binops_on_constants() function完成:

/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP
   with    LOAD_CONST binop(c1,c2)
   The consts table must still be in list form so that the
   new constant can be appended.
   Called with codestr pointing to the first LOAD_CONST.
   Abandons the transformation if the folding fails (i.e.  1+'a').
   If the new constant is a sequence, only folds when the size
   is below a threshold value.  That keeps pyc files from
   becoming large in the presence of code like:  (None,)*1000.
*/

考虑到 Python 是一种高度动态的语言,此类优化只能应用于以后无法动态替换的文字和常量。