为什么在Python 3中将True和False更改为关键字

时间:2013-08-05 04:55:45

标签: python keyword

在Python 2中,我们可以重新分配TrueFalse(但不是None),但全部三个(TrueFalse和{{ 1}})被认为是内置变量。但是,在Py3k中,所有三个都按the docs更改为关键字。

从我自己的推测中,我只能猜测是为了防止像this这样的恶作剧来自旧的None恶作剧。但是,在Python 2.7.5中,也许在之前,重新分配True, False = False, True的{​​{1}}等语句引发了None = 3

从语义上讲,我不认为NoneSyntaxError: cannot assign to NoneTrue是关键字,因为它们最后是语义文字,这就是Java所做的。我检查了PEP 0(索引),我找不到PEP解释它们被改变的原因。

是否有性能优势或其他原因使它们成为关键字而不是文字或特殊包装它们如python2中的False

3 个答案:

答案 0 :(得分:44)

可能是因为Python 2.6不仅允许True = False,还允许你说出有趣的话:

__builtin__.True = False

会在整个过程中将True重置为False。它可能导致真正有趣的事情发生:

>>> import __builtin__
>>> __builtin__.True = False
>>> True
False
>>> False
False
>>> __builtin__.False = True
>>> True
False
>>> False
False

编辑:正如Mike所指出的,Python wiki还在核心语言更改下声明了以下内容:

  • 制作真假关键字。
    • 原因:无法分配给他们。

答案 1 :(得分:11)

主要有两个原因:

  1. 所以人们不会在随机模块上隐藏__builtin__.True = False恶作剧。 (由devnull解释)
  2. 因为关键字比全局内置更快。在Python 2.x中,解释器必须在使用它们之前解析这些变量的值,这比关键字慢一点。 (见Why is if True slower than if 1?

答案 2 :(得分:3)

几个月前在python-dev上讨论过这个问题。 有大量链接到True的定义会很烦人,这与链接到例如nonlocal或with statements doc。

我得出的结论是,为什么“真与假”会使事情“更加精细”。

  1. 重新绑定为循环内调用的函数的副作用。

    改变True非常容易,例如:

    def True(): print True

  2. 让用户代码重新绑定内置名称None,True和False没有很好的用例,这使得它们几乎只有关键字。

  3. 让程序必须在每一步中的符号表中查找“True”才发现True具有值True远非直观。 (这就是为什么1比True快。)

      

    x = compile('while 1:foop()','','exec')

         

    dis.dis(x)的

          0 SETUP_LOOP              19 (to 22)
          3 JUMP_FORWARD             4 (to 10)
          6 JUMP_IF_FALSE           11 (to 20)
          9 POP_TOP
    >>   10 LOAD_NAME                0 (foop)
         13 CALL_FUNCTION            0
         16 POP_TOP
         17 JUMP_ABSOLUTE           10
    >>   20 POP_TOP
         21 POP_BLOCK
    >>   22 LOAD_CONST               1 (None)
         25 RETURN_VALUE
    
  4.   

    x = compile('while True:foop()','','exec')

         

    dis.dis(x)的

              0 SETUP_LOOP              19 (to 22)
        >>    3 LOAD_NAME                0 (True)
              6 JUMP_IF_FALSE           11 (to 20)
              9 POP_TOP
             10 LOAD_NAME                1 (foop)
             13 CALL_FUNCTION            0
             16 POP_TOP
             17 JUMP_ABSOLUTE            3
        >>   20 POP_TOP
             21 POP_BLOCK
        >>   22 LOAD_CONST               0 (None)
             25 RETURN_VALUE
    

    参考:

    与分配为True和False有关的开始谈话:

    一些辅助数据:

    PS:某些数字显示True / 1:

    [alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
    'while True:' '  if c.next()>99: break'
    10000 loops, best of 3: 91 usec per loop
    
    [alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
    'while 1:' '  if c.next()>99: break'
    10000 loops, best of 3: 76 usec per loop