我正在探索REPL,我注意到__builtins__
模块。
我进入了
>>> __builtins__.
然后点击Tab,然后Python REPL向我展示了内置标识符的列表,包括abs
,len
,zip
和True
, False
,None
等。
毫无疑问,第一次测试通过了:
>>> __builtins__.zip is zip
True
但第二个没有:
>>> __builtins__.None is None
File "<stdin>", line 1
__builtins__.None is None
^
SyntaxError: invalid syntax
为什么?
答案 0 :(得分:5)
None
是一个关键字。因此,它不能与点表示法一起使用,就像__builtins__.True
,__builtins__.class
和__builtins__.def
也是语法错误一样。
使用getattr
:
print(getattr(__builtins__, 'None') is None)
# True
print(getattr(__builtins__, 'False') is False)
# True
print(getattr(__builtins__, 'True') is True)
# True
与abs
,len
,zip
等(顶级函数)不同,None
,True
和False
是关键字在Python 3中(见https://docs.python.org/3/reference/lexical_analysis.html#keywords)。
在Python 2中True
和False
不是关键字(只是内置名称/常量)(请参阅https://docs.python.org/2/reference/lexical_analysis.html#keywords),以便您可以重新分配给他们。如上所述,这在Python 3中是不可能的,因为它们成了关键字。
另请参阅此问题:True=False assignment in Python 2.x
话虽如此,人们仍然可以在Python 3中使用__builtins__.True
,但它不会像以前在Python 2中那样影响实际True
:
print(getattr(__builtins__, 'True'))
# True
setattr(__builtins__, 'True', False)
print(getattr(__builtins__, 'True'))
# False
print(True)
# True
答案 1 :(得分:1)
我们可以在Python 2和Python 3的关键字列表中观察到该语言的这种变化。 False
,None
和True
被添加为关键字,以避免混淆尝试覆盖其中一个。
>>> False=True
>>> False
True
这是有效的,但却极具误导性,Python 2. Python 3的反应不同:
>>> False=True
File "<stdin>", line 1
SyntaxError: can't assign to keyword
Python的历史记录在the story of None, True and False上有一篇文章。 这是关于该主题的另一个stack overflow question。这种变化的另一个影响是编译器确切地知道它们是哪些对象,并且在引用它们时不需要命名空间查找。
Python 2:
>>> dis.dis(compile("True","foo.py","eval"))
1 0 LOAD_NAME 0 (True)
3 RETURN_VALUE
Python 3:
>>> dis.dis(compile("True","foo.py","eval"))
1 0 LOAD_CONST 0 (True)
3 RETURN_VALUE