【问题标题】:I want my Python script to detect the version and quit gracefully in case of a mismatch我希望我的 Python 脚本检测版本并在不匹配的情况下优雅退出
【发布时间】:2010-03-03 03:34:36
【问题描述】:

我想让它尽可能通用 - 例如处理尽可能多的版本。

由于版本 3 不向后兼容版本 2,因此我想确保使用正确的打印语句。

如果您有任何问题,请告诉我,并随时根据可用的内容(例如库)分享与动态逻辑有关的相关知识。

假设我有一个只能在 1.x、2.x 或 3.x 版本下运行的脚本。

或需要库 A 或库 B 的脚本。

谢谢!

编辑:

现在......当涉及到 Python(与 .Net 不同)时,SciPy、Google App Engine 等一些库让您始终专注于特定版本。在 Linux、Mac Os 上,您可以在命令行上在不同的 Python 安装之间切换。这就是我想避免混淆的原因——我想记住哪个脚本适用于哪个版本的 Python 以及它需要哪些库。我宁愿让它以人类可读的方式失败。

【问题讨论】:

  • 请不要在 Python 2 和 Python 3 之间混用语法。请不要。有一个 2to3 工具可以将您的正确 Python 2 重写为 Python 3。您维护 Python 2 版本,并使用该工具创建 Python 3 版本。这个工具保证你没有任何困惑。您维护 Python 2 并干净利落地转换为 Python 3。
  • @S.Lott 虽然“正确”的 Python 2 似乎意味着为仅 Python 2.6 的语法编写一些东西,这意味着您必须放弃对 2.5 及以下版本的支持。特别是使用bytes()b''来表示字节串。

标签: python version


【解决方案1】:

如果您想在版本 2 和 3 之间混合使用语法,则必须使用条件导入来解决语法错误。

# just psuedocode
if version is x:
   import lib_x # contains version x implementation
else:
   import lib_y # contains version y compatible implementation

不建议尝试保持python3和旧版本之间的兼容性。也就是说,这里有几种检测正在使用的 python 版本的方法:

sys.hexversion 虽然不是特别人性化,但可以在最广泛的 python 版本中使用,因为它是在 1.5.2 版中添加的:

import sys
if sys.hexversion == 0x20505f0:
    print "It's version 2.5.5!"

您应该可以从sys.version_info(python 2.0 中添加)获取版本信息:

import sys
if sys.version_info[0] == 2:
    print "You are using version 2!"
else:
    print "You are using version 1, because you would get SyntaxErrors if you were using 3!"

您也可以使用平台模块,尽管它是在 python 2.3 中引入的,并且在旧版本中不可用(假设您甚至关心它们):

try:
    import platform
    if platform.python_version().startswith('2'):
        print "You're using python 2.x!"
except ImportError, e:
    print "You're using something older than 2.3. Yuck."

【讨论】:

  • 我想就这么简单。当然它必须是 print 或 print()。谢谢!
  • sys.version_info 是一个包含版本 X.Y.Z 的元组,而不是一个函数。
  • 以防万一,我确实关心旧版本。顺便说一句,您的第二次编辑不适用于 Python 3.x :(
  • 第二次编辑不适用于任何 Python 版本。 sys.version_info 一直是一个元组,而不是一个函数。他的代码是错误的。
  • 2.0 版首次提供。
【解决方案2】:

sys 模块还包含版本信息(在 2.0 版本中首次提供):

import sys

if sys.version_info[0] == 2:
    print("You are using Python 2.x")
elif sys.version_info[0] == 3:
    print("You are using Python 3.x")

【讨论】:

  • 如果代码包含在一个 PY 版本中被认为是错误但在另一个 PY 版本中被认为是错误的语法,这是 无用!在这种情况下,编译器将停止,上面的代码将永远不会被执行!非常有趣的是,答案的所有者、它的编辑、所有支持者以及可能大多数读者都错过了这个! (这是一个反对投票的经典案例,我从来没有这样做过。我更喜欢指出错误而不是“惩罚”它们。)
【解决方案3】:

如果唯一的问题是你想使用正确的打印语句来避免语法错误,你可以通过使用 Python 2.6 中的 print() 函数来完全避免这个问题:

if sys.version_info[0:2] == (2,6):           # Or you could use try/except here
    from __future__ import print_function
print("Now you can use print as a function regardless of whether you're on 2.6 or 3.x!")

当然,如果你还想支持早期版本的 Python,这是行不通的。

【讨论】:

  • 我想做很多事情。这是值得深思的。谢谢。
  • 您似乎想要一个无条件 from __future__ import print_function 这里。该版本在 2.6 上仍然可以正常工作,但不会像您的那样与 2.7 中断。 (这就是我所说的通过检查版本信息来处理不同版本是脆弱的。)
【解决方案4】:
  • 如果您想维护一个适用于 Python 2 和 3 的代码库,您不会尝试编写可以在两者中运行的代码,这会很尴尬、丑陋且容易出错,您应该编写在 Python 2 中并使用 2to3 进行转换。 (您也可以用 Python 3 编写并使用 3to2 进行转换,但我认为该工具还不够成熟。)2to3 并不完美,但是制作可以通过它转换的 Python 2 代码比制作更有意义将在 Python 3 解释器中运行的 Python 2 代码。 编辑:这是 2010 年的普遍看法,但事实并非如此。要做的就是写一个多语种。 2to3 最终并没有那么有用

  • 另一个选项是Cython,这是一种类似 Python 的语言,可用于创建 C 扩展模块。 Cython 模块可与 Python 2 和 3 一起使用。

  • 当您支持多个版本的 Python 时,通常最好直接检查您想要的功能而不是检查版本号。直接检查版本号是脆弱和间接的。

    例如,如果我想要可以在 Python 2.5 之前使用的代码,我会说:

    try: 
        any
    except NameError:
        def any(iterable):
            for item in iterable:
                if item:
                    return True
            return False
    

    (请注意,这几乎是捕获NameError 的唯一原因)。同样,可以通过捕获ImportError 来检查库的可用性。 编辑:现在有大量工具可以将其抽象出来。

  • 如果您想让脚本记住它来自哪个版本,就像您说的那样,根本不用费心去支持多个版本。将正确的版本号二进制文件放入 shebang 行并基于此运行脚本。

【讨论】:

  • +1:使用 2to3,这就是它的用途。编写能正确转换的 Python 2,不要尝试混合语法。
  • 2015 年,大量的模块是用 Python 2 和 3 兼容的代码编写的,使用像 six 这样的库,使过程更加简单。
【解决方案5】:

仅供参考,如果您想将 2.x 脚本移植到 3.x,可以使用 2to3 source conversion tool

【讨论】:

  • @hamish :不完全是......但它使大部分过程自动化......请参阅:diveintopython3.org/porting-code-to-python-3-with-2to3.html
  • @Hamish Grubijan:是的。这是“一尘不染”。如果您正确编写 Python 2(这很容易做到),2to3 工具将转换为 Python 3,您不会有任何困惑或任何思考或任何维护。这是让代码在两种环境中运行的最佳方式。您编写(和维护)Python 2 并使用 2to3 工具来创建您的 Python 3。
【解决方案6】:

在 Linux、Mac 等上,您应该使用标准的第一行:

#!/usr/bin/env python2

#!/usr/bin/env python2.6

#!/usr/bin/env python3

在 Windows 上,从文档的角度来看,有这样的第一行很有用,即使 Windows 不使用它来选择解释器。

【讨论】:

    猜你喜欢
    • 2018-08-29
    • 2014-12-10
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多