如果我有一个Python脚本,至少需要一个特定的
在Python版本中,优雅地失败的正确方式是什么
当使用早期版本的Python启动脚本时?
如何尽早获得控制权以发出错误消息
并退出吗?
For example, I have a program that uses the ternery operator (new in 2.5) and "with" blocks
(new in 2.6). I wrote a simple little interpreter-version
checker routine which is the first thing the script would
call ... except it doesn't get that far. Instead, the
script fails during python compilation, before my routines
are even called. Thus the user of the script sees some very
obscure synax error tracebacks - which pretty much require
an expert to deduce that it is simply the case of running
the wrong version of Python.
我知道如何检查Python的版本。问题是一些语法在旧版本的Python中是非法的。考虑这个程序:
import sys
if sys.version_info < (2, 4):
raise "must use python 2.5 or greater"
else:
# syntax error in 2.4, ok in 2.5
x = 1 if True else 2
print x
当在2.4下运行时,我想要这个结果
$ ~/bin/python2.4 tern.py
must use python 2.5 or greater
而不是这个结果:
$ ~/bin/python2.4 tern.py
File "tern.py", line 5
x = 1 if True else 2
^
SyntaxError: invalid syntax
(为同事通灵。)
尽管问题是
我如何尽早获得控制以发出错误消息并退出?
我回答的问题是:
我如何获得足够早的控制,在启动应用程序之前发出错误消息?
我的回答和其他帖子有很大不同。
到目前为止,似乎答案都试图从Python内部解决你的问题。
我建议,在启动Python之前进行版本检查。我知道你的路径是Linux或unix。
但是我只能给你一个Windows脚本。我认为使它适应linux脚本语法不会太难。
下面是2.7版的DOS脚本:
@ECHO OFF
REM see http://ss64.com/nt/for_f.html
FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul
IF NOT ErrorLevel 1 GOTO Python27
ECHO must use python2.7 or greater
GOTO EOF
:Python27
python.exe tern.py
GOTO EOF
:EOF
这不会运行应用程序的任何部分,因此不会引发Python异常。它不创建任何临时文件或添加任何操作系统环境变量。它不会因为不同的版本语法规则而导致应用程序出现异常。这样就少了三个安全入口。
FOR /F行是关键。
FOR /F "tokens=1,2" %%G IN ('"python.exe -V 2>&1"') DO ECHO %%H | find "2.7" > Nul
对于多个python版本,请检查url:
http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=17
我的hack版本是:
[女士脚本;Python模块启动前检查Python版本
http://pastebin.com/aAuJ91FQ
我正在扩展akhan的出色回答,它甚至在编译Python脚本之前就打印了有用的消息。
如果你想确保脚本在Python 3.6或更新版本中运行,请在Python脚本顶部添加这两行:
#!/bin/sh
''''python3 -c 'import sys; sys.exit(sys.version_info < (3, 6))' && exec python3 -u -- "$0" ${1+"$@"}; echo 'This script requires Python 3.6 or newer.'; exit 1 # '''
(注意:第二行以四个单引号开始,以三个单引号结束。这看起来可能很奇怪,但这不是打字错误。)
这种解决方案的优点是,如果使用的是3.6以上的Python版本,像print(f' hello, {name}!')这样的代码不会引起SyntaxError。你会看到这条有用的信息:
This script requires Python 3.6 or newer.
当然,此解决方案仅适用于类unix的shell,并且仅适用于直接调用脚本(例如:./script.py),并设置了适当的eXecute权限位。