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

Why were True and False changed to keywords in Python 3

在python 2中,我们可以重新分配TrueFalse(但不是None),但这三个(TrueFalseNone)都被认为是内置变量。但是,在PY3K中,所有三个都根据文档更改为关键字。

根据我自己的猜测,我只能猜测,这是为了防止像这样的恶作剧,这种恶作剧源自于老江户的恶作剧。然而,在python 2.7.5中,或者在之前,像None = 3这样重新分配None的语句引发了SyntaxError: cannot assign to None

在语义上,我不相信EDOCX1 0,EDOCX1,1,EDCOX1,2个词都是关键字,因为它们最后是语义上的文字,这就是Java所做的。我查了一下PEP 0(索引),但找不到PEP来解释它们为什么会发生变化。

是否有性能优势或其他原因使它们成为关键字,而不是文字或特殊大小写,如python2中的None


可能是因为python 2.6不仅允许True = False,而且允许您说一些有趣的事情,比如:

1
__builtin__.True = False

这将在整个过程中将True重置为False。它会导致非常有趣的事情发生:

1
2
3
4
5
6
7
8
9
10
11
>>> import __builtin__
>>> __builtin__.True = False
>>> True
False
>>> False
False
>>> __builtin__.False = True
>>> True
False
>>> False
False

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

  • 使关键字为真或假。
    • 理由:不可能分配给他们。


主要有两个原因:

  • 所以人们不会做隐藏在随机模块中的__builtin__.True = False恶作剧。(由devnull解释)
  • 因为关键字比全局内置的要快。在python 2.x中,解释器必须先解析这些变量的值,然后才能使用它们,这比关键字慢一点。(看为什么如果真的比如果1慢?)

  • 几个月前在python-dev上讨论过这个问题。与非本地或带语句文档的链接相反,大量链接到"真"的定义会很烦人。

    我得出的结论是,真实和虚假的事物会使事物"更加美好"。

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

    很容易改变事实,例如:

    def True():
    print True

  • 对于让用户代码重新绑定内置名称"无"、"真"和"假",实际上没有什么好的用例,使得它们的关键字几乎只有加号。

  • 使程序在每一步都要在符号表中查找"真"才发现真的有值真是不直观的。(这就是为什么1比真的快。)


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

    dis.dis(x)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
          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
  • x=compile('while True: foop()', '', 'exec')

    dis.dis(x)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
              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

    参考文献:

    • http://mail.python.org/pipermail/python-checkins/2011-9月/107641.html
    • http://mail.python.org/pipermail/python-checkins/2012-1月/110353.html
    • https://groups.google.com/forum/!搜索in/comp.lang.python/false$20true$20keyword/comp.lang.python/65b6qwuf8wi/hwq5pwnw7woj

    开始谈论分配给"真"和"假"的相关内容:

    • http://bugs.python.org/issue2349
    • https://groups.google.com/forum/comp.lang.python/65b6qwuf8wi/hwq5pww7woj

    一些辅助数据:PS:有些数字显示为真/1:

    1
    2
    3
    4
    5
    6
    7
    [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