而(1)比。 for while(真) – 为什么会有差异?

在这个关于perl中的无限循环的问题中有所提及: while(1)Vs. for(;;)有速度差吗? ,我决定在Python中运行一个类似的比较。 我期望编译器会为while(True): passwhile(1): pass生成相同的字节码,但实际上在python2.7中并不是这样。

以下脚本:

 import dis def while_one(): while 1: pass def while_true(): while True: pass print("while 1") print("----------------------------") dis.dis(while_one) print("while True") print("----------------------------") dis.dis(while_true) 

产生以下结果:

 while 1 ---------------------------- 4 0 SETUP_LOOP 3 (to 6) 5 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE while True ---------------------------- 8 0 SETUP_LOOP 12 (to 15) >> 3 LOAD_GLOBAL 0 (True) 6 JUMP_IF_FALSE 4 (to 13) 9 POP_TOP 9 10 JUMP_ABSOLUTE 3 >> 13 POP_TOP 14 POP_BLOCK >> 15 LOAD_CONST 0 (None) 18 RETURN_VALUE 

while True使用显然更复杂。 为什么是这样?

在其他上下文中,python的行为就像True等于1:

 >>> True == 1 True >>> True + True 2 

为什么while区分两者?

我注意到python3使用相同的操作来评估语句:

 while 1 ---------------------------- 4 0 SETUP_LOOP 3 (to 6) 5 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE while True ---------------------------- 8 0 SETUP_LOOP 3 (to 6) 9 >> 3 JUMP_ABSOLUTE 3 >> 6 LOAD_CONST 0 (None) 9 RETURN_VALUE 

python3有没有改变,以评估布尔值的方式?

在Python 2.x中, True不是关键字,而是一个内置的全局常量 ,在booltypes中定义为1。 所以解释器还是要加载True的内容。 换句话说, True是可重新分配的:

 Python 2.7 (r27:82508, Jul 3 2010, 21:12:11) [GCC 4.0.1 (Apple Inc. build 5493)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> True = 4 >>> True 4 

在Python 3.x中它确实成为一个关键字和一个真正的常量:

 Python 3.1.2 (r312:79147, Jul 19 2010, 21:03:37) [GCC 4.2.1 (Apple Inc. build 5664)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> True = 4 File "<stdin>", line 1 SyntaxError: assignment to keyword 

因此解释器可以用无限循环取代while True:循环。

这不太对,

因此解释器可以用无限循环取代True:循环。

因为人们仍然可以跳出循环。 但是确实,这样一个循环的else子句永远不会在Python 3中被访问。同样,简化值查找也是事实,使得它在Python 2中运行得和while 1一样快。

性能比较

演示一个稍微不重要的while循环的时间差异:

build立

 def while1(): x = 0 while 1: x += 1 if x == 10: break def whileTrue(): x = 0 while True: x += 1 if x == 10: break 

Python 2

 >>> import timeit >>> min(timeit.repeat(while1)) 0.49712109565734863 >>> min(timeit.repeat(whileTrue)) 0.756627082824707 

Python 3

 >>> import timeit >>> min(timeit.repeat(while1)) 0.6462970309949014 >>> min(timeit.repeat(whileTrue)) 0.6450748789939098 

说明

为了解释这个区别,在Python 2中:

 >>> import keyword >>> 'True' in keyword.kwlist False 

但在Python 3中:

 >>> import keyword >>> 'True' in keyword.kwlist True >>> True = 'true?' File "<stdin>", line 1 SyntaxError: can't assign to keyword 

由于True是Python 3中的一个关键字,因此解释器不必查找该值是否有人用其他值replace它。 但是,由于可以将True分配给另一个值,因此解释者每次都必须查看它。

Python 2的结论

如果你在Python 2中有一个紧密的,长期运行的循环,你可能应该使用while 1:而不是while True:

Python 3的结论

使用的while True:如果你没有条件打破你的循环。