我可以在解释器解析代码之前断言 python 版本吗?

Can I assert the python version before the interpreter parses the code?

我想通知用户他们应该使用哪个 python 版本:

import sys
assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"
print(f"a format string")

但是,运行 上述文件出现语法错误:

$ python fstring.py. # default python is 2.7
  File "fstring.py", line 3
    print(f"a format string")
                           ^
SyntaxError: invalid syntax

是否可以针对每个文件执行此操作,而不用将所有 f 字符串包装在 try 块中?

不,这在 per-file 基础上是不可能的,因为整个文件的解析发生在执行任何文件之前,因此在检查任何断言之前。 try 也行不通,同理。

唯一可行的方法是将代码的一部分的解析推迟到运行时,方法是将代码放入字符串中并调用 eval,但是...不要那样做。您有两个明智的选择:根本不使用 f-strings,或者让它失败并显示 SyntaxError 而不是您自己的自定义错误消息。

或者,如果您在 Unix 或 Linux 系统上工作,那么您可以将文件标记为可执行文件并在开头给它一个 shebang 行,例如 #!/usr/bin/python3.8 以便用户不需要知道自己使用的正确版本。

如果您想在 per-module 的基础上执行此操作,请参阅@Chris 的回答。

如果您正在编写模块,您可以通过模块的 __init__.py 来完成,例如如果你有类似

  • foo_module/
    • __init__.py
    • foo_module/
      • foo.py
    • setup.py

其中 __init__.py 包含

import sys


assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"

foo.py包含

print(f"a format string")

示例:

Python 2.7.18 (default, Jun 23 2020, 19:04:42) 
[GCC 7.5.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from foo_module import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "foo_module/__init__.py", line 4, in <module>
    assert sys.version_info >= (3, 6), "Use Python 3.6 or newer"
AssertionError: Use Python 3.6 or newer