“while 1”和“while True”有什么区别?

28 投票
11 回答
36644 浏览
提问于 2025-04-15 19:16

我看到有两种方法可以在Python中创建一个无限循环:

  1. while 1:
        do_something()
    
  2. while True:
        do_something()
    

这两种方法有什么区别吗?有没有哪种方法更符合Python的风格?

11 个回答

5

其实这没什么特别的。两种写法都不难读懂,不过我个人更喜欢用 while True,因为它更明确一些。

更一般来说,很多人写的 Python 中的 while–break 循环其实可以用其他方式来实现。有时候我看到有人写 i = 0; while True: i += 1 ...,这可以用 for i in itertools.count() 来替代。而且还有人写 while True: foo = fun() if foo is None: break,其实这可以用 for foo in iter(fun, None) 来实现。虽然这些新写法需要学习,但它们的代码更简洁,也不容易出错。

12

最符合Python风格的写法总是最容易读懂的。可以使用 while True: 这个写法。

48

其实这两者之间的细节并不重要,这些小差别并不会影响一个东西是否“符合Python风格”。

不过,如果你对这些小知识感兴趣的话,还是有一些区别的。

  1. 内置的布尔类型在Python 2.3之前是不存在的,所以那些打算在老版本上运行的代码通常会用 while 1: 这种写法。你在标准库中也能看到这种写法。

  2. 在Python 3之前,TrueFalse 这两个内置值并不是保留字,所以可以被重新赋值,改变它们的值。这在上面的情况中是有帮助的,因为代码可以用 True = 1 来保持向后兼容,但这也意味着每次使用 True 时都需要在全局字典中查找它。

  3. 由于上面的限制,Python 2编译出来的字节码和Python 3是不同的,因为Python 2无法对 True 使用常量整数的优化。Python在编译 1 时可以判断它总是非零的,因此会去掉条件跳转,根本不加载这个常量:

    >>> import dis
    >>> def while_1():
    ...     while 1:
    ...         pass
    ...
    >>> def while_true():
    ...     while True:
    ...         pass
    ...
    >>> dis.dis(while_1)
      2           0 SETUP_LOOP               5 (to 8)
    
      3     >>    3 JUMP_ABSOLUTE            3
                  6 POP_TOP
                  7 POP_BLOCK
            >>    8 LOAD_CONST               0 (None)
                 11 RETURN_VALUE
    >>> dis.dis(while_true)
      2           0 SETUP_LOOP              12 (to 15)
            >>    3 LOAD_GLOBAL              0 (True)
                  6 JUMP_IF_FALSE            4 (to 13)
                  9 POP_TOP
    
      3          10 JUMP_ABSOLUTE            3
            >>   13 POP_TOP
                 14 POP_BLOCK
            >>   15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE
    

所以,while True: 读起来更简单,而 while 1: 对老版本的Python更友好。现在你不太可能需要在Python 2.2上运行代码,或者担心循环的字节码数量,所以前者稍微更好一些。

撰写回答