拼写错误的 __future__ 导入导致稍后在脚本中出现错误,而不是在导入位置
Misspelled __future__ import causes error later in script, not at import location
我发现了一些奇怪的地方,我在 from __future__ import printfunction
中不小心将 printfunction
拼错为 printfuncion
。这并没有像我预期的那样在 import 语句的位置给我一个错误,而是 import 语句似乎被忽略了,当我试图在一个与 print
的语句形式不兼容的方式。这使得错误的真正原因比其他情况下更不明显
谁能解释为什么在 import
行没有发现错误?
文件'bad_printfunc_import.py':
#!/usr/bin/env python
from __future__ import printfuncion
print('I will use the named param "sep" in this fuction call.',
'That will cause an error, as with print as a statement',
'rather than a function, these arguments will presumably be',
'interpretted as a tuple rather than function arguments,',
'and tuples can\'t have named elements.',
sep='\n')
产生错误:
$ ./bad_printfunc_import.py
File "./bad_printfunc_import.py", line 10
sep='\n')
^
SyntaxError: invalid syntax
有趣的是,如果我从文件中删除 print
调用,那么我会在 import
行收到错误:
$ ./bad_printfunc_import.py
File "./bad_printfunc_import.py", line 3
from __future__ import printfuncion
SyntaxError: future feature printfuncion is not defined
它通常会在导入失败之前报告语法错误,这对我来说确实有意义,但是当强制执行的语法依赖于 __future__
导入时,这就没有意义了!
from future ...
导入的特殊之处在于它们设置了可以影响两个组件的标志:解析器和编译器。如果缺少标志,解析和编译都可能失败,但解析器不会报告编译器可能会接受的拼写错误的名称。
禁用 print
语句是一个影响解析器的标志(连同 with_statement
和 unicode_literals
标志),因此解析器只查找 那些旗帜。因此,由于没有找到 print_function
关键字,因此未设置禁用 print
语句的解析器标志,并且解析失败,这会导致语法错误。
只有到达编译阶段才会Python抛出错误名称的语法错误:
>>> compile('''from __future__ import nonsuch; parser error here''', '', 'exec')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "", line 1
from __future__ import nonsuch; parser error here
^
SyntaxError: invalid syntax
>>> compile('''from __future__ import nonsuch''', '', 'exec')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "", line 1
SyntaxError: future feature nonsuch is not defined
理论上,解析器可以在编译器到达它们之前尽早报告无效的 from __future__
名称,但这会使解析器进一步复杂化。就目前而言,parser already manually looks for those 3 special flags,而编译器只能依赖解析后的 AST。每次都必须检查所有 7 个可能的名称会增加编译器已经捕获的错误的复杂性。
我发现了一些奇怪的地方,我在 from __future__ import printfunction
中不小心将 printfunction
拼错为 printfuncion
。这并没有像我预期的那样在 import 语句的位置给我一个错误,而是 import 语句似乎被忽略了,当我试图在一个与 print
的语句形式不兼容的方式。这使得错误的真正原因比其他情况下更不明显
谁能解释为什么在 import
行没有发现错误?
文件'bad_printfunc_import.py':
#!/usr/bin/env python
from __future__ import printfuncion
print('I will use the named param "sep" in this fuction call.',
'That will cause an error, as with print as a statement',
'rather than a function, these arguments will presumably be',
'interpretted as a tuple rather than function arguments,',
'and tuples can\'t have named elements.',
sep='\n')
产生错误:
$ ./bad_printfunc_import.py
File "./bad_printfunc_import.py", line 10
sep='\n')
^
SyntaxError: invalid syntax
有趣的是,如果我从文件中删除 print
调用,那么我会在 import
行收到错误:
$ ./bad_printfunc_import.py
File "./bad_printfunc_import.py", line 3
from __future__ import printfuncion
SyntaxError: future feature printfuncion is not defined
它通常会在导入失败之前报告语法错误,这对我来说确实有意义,但是当强制执行的语法依赖于 __future__
导入时,这就没有意义了!
from future ...
导入的特殊之处在于它们设置了可以影响两个组件的标志:解析器和编译器。如果缺少标志,解析和编译都可能失败,但解析器不会报告编译器可能会接受的拼写错误的名称。
禁用 print
语句是一个影响解析器的标志(连同 with_statement
和 unicode_literals
标志),因此解析器只查找 那些旗帜。因此,由于没有找到 print_function
关键字,因此未设置禁用 print
语句的解析器标志,并且解析失败,这会导致语法错误。
只有到达编译阶段才会Python抛出错误名称的语法错误:
>>> compile('''from __future__ import nonsuch; parser error here''', '', 'exec')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "", line 1
from __future__ import nonsuch; parser error here
^
SyntaxError: invalid syntax
>>> compile('''from __future__ import nonsuch''', '', 'exec')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "", line 1
SyntaxError: future feature nonsuch is not defined
理论上,解析器可以在编译器到达它们之前尽早报告无效的 from __future__
名称,但这会使解析器进一步复杂化。就目前而言,parser already manually looks for those 3 special flags,而编译器只能依赖解析后的 AST。每次都必须检查所有 7 个可能的名称会增加编译器已经捕获的错误的复杂性。