【问题标题】:Is there a standard way to make sure a python script will be interpreted by python2 and not python3?有没有一种标准方法来确保 python 脚本将由 python2 而不是 python3 解释?
【发布时间】:2011-04-04 22:42:45
【问题描述】:

是否有一种标准方法可以确保 python 脚本由 python2 而不是 python3 解释?在我的发行版中,我可以使用 #!/usr/bin/env python2 作为 shebang,但似乎并非所有发行版都提供“python2”。我可以显式调用 python 的特定版本(例如 2.6),但这会排除没有该版本的人。

在我看来,当发行版开始将 python3 作为默认的 python 解释器时,这将成为一个越来越大的问题。

【问题讨论】:

    标签: python unix scripting python-3.x shebang


    【解决方案1】:

    http://docs.python.org/library/sys.html#sys.version_info

    使用 sys 模块,您可以确定正在运行的 python 版本并引发异常或退出或任何您喜欢的。

    更新:

    您可以使用它来调用适当的解释器。例如,设置一个为您进行检查的小脚本,并在 shbang 中使用它。它会检查正在运行的 python 版本,如果不是你想要的,就会寻找你想要的。然后它会在那个版本的 python 中运行脚本(或者如果没有发现任何好的东西就会失败)。

    【讨论】:

      【解决方案2】:

      在很长的过渡时期内,这是一个有点混乱的问题。不幸的是,没有万无一失的跨平台方法来保证正在调用哪个 Python 版本,除了让 Python 脚本本身在启动后进行检查。许多(如果不是大多数)发布 Python 3 的发行版确保通用 python 命令默认别名为最新的 Python 2 版本,而 python3 别名为最新的 Python 3。那些不应该的发行版鼓励这样做。但是不能保证用户不会覆盖它。我认为在可预见的未来可用的最佳实践是让打包者、分销商和用户假设python 指的是 Python 2,并在必要时在脚本中构建运行时检查。

      【讨论】:

      • 并且,如果有必要,正如 kwatford 在他的评论中指出的那样,在安装时在包的 setup.py 脚本或等效项中包含一个检查,因为 setuptoolsDistributepip 等.通常会更改脚本的 shebang 行以指向正在安装的 Python 实例。
      • 恕我直言,总是应该有可用的符号链接python2,以便将来制作clearly distinguishable shebangs
      • @Grzegorz:Python PEP 394 在该主题上是开放的,并且可能会在未来的 Python 2 更新中实现:bugs.python.org/issue12627
      【解决方案3】:

      使用sys.version_info,您可以对其进行简单的价值测试。例如,如果您只想支持 2.6 或更低版本:

      import sys
      if sys.version_info > (2,6):
          sys.exit("Sorry, only we only support up to Python 2.6!")
      

      【讨论】:

      • 这不是我想要的,我希望自动选择好的解释器,而不是在选择错误时打印错误消息:-/
      • 您的问题的最终答案是:“不,没有标准方法可以确保 python 脚本将由 python2 而非 python3 解释。”您要求的是确保选择 Python2 而不是 3。您没有指定要自动选择正确的解释器。您可能能够确定这样做的唯一方法是在程序被调用(例如使用 shell 脚本)之前实施检查,然后针对所需的 Python 解释器运行您的 Python 代码。
      • 期望“自动选择好的翻译”是荒谬的。文件不能强制哪个程序运行它。
      【解决方案4】:

      情况不太一样,但我工作的公司有一个可以运行 Python 脚本的应用程序(在它的众多功能中)。在各种平台上涉及 Python 安装的众多支持问题之后,我们决定只在应用程序中安装我们自己的 Python 解释器。这样我们就可以准确地知道它的安装位置和版本。对于您的需求,这种方法可能过于繁重(Python 包仅占我们应用程序的 10% 左右),但它确实有效。

      【讨论】:

      • 这实际上是一种很好的方法,可以消除如此严格的要求所需的所有工作。
      【解决方案5】:

      我猜这取决于你如何分发它。

      如果您使用普通的setup.py 文件来管理您的发行版,如果用户尝试在 Python 3 中安装它,请让它崩溃。

      安装后,由(比如)setuptools 创建的控制台脚本的 shebang 可能会链接到用于安装它的特定解释器。

      如果您在安装过程中做了一些奇怪的事情,您可以在您使用的任何安装脚本中查找 python 解释器并存储一个选项。您可能首先检查所谓的“python”是否是 2.x。如果没有,请检查“python2.7”、“python2.6”等以查看可用的内容。

      【讨论】:

        【解决方案6】:

        据我了解,不同的发行版将位于您驱动器的不同位置。以下是我想到的一些建议 -

        1. 您可以使用 UNIX 别名来创建指向不同发行版的快捷方式。例如:别名 py2="/usr/bin/python2.X"。因此,当您运行脚本时,您可以使用 py2 xx.py
        2. 或者其他方式可能是修改您的 PYTHON_PATH 环境变量。
        3. 或者,如果我没记错的话,sys 模块中有一条规定可以获取当前的 python 版本号。你可以得到它并适当地处理。

        应该这样做...

        【讨论】:

        • 我正在分发一个 python 应用程序,我的问题是确保 所有用户 使用 python2.x 来运行我的应用程序。
        【解决方案7】:

        您可以使用自动工具来选择 Python 2 解释器。 Here 是如何做到这一点的。保证正确的shebang可能很难优雅地做到。 here 是一种方法。简单地拥有一个轻量级的 Bash 包装脚本 wrapper.sh.in 可能会更容易,看起来像:

        #!/bin/bash
        PYTHON2="@PYTHON@" #That first link enables this autotool variable
        "$PYTHON2" "$@"  #Call the desired Python 2 script with its arguments
        

        打电话给wrapper.sh(在./configure之后)喜欢:

        ./wrapper.sh my_python2_script.py --an_option an_argument
        

        【讨论】:

          【解决方案8】:

          我相信这会满足您的要求,即测试低于 3.x 的非特定 Python 版本(只要它不包含 from __future__ import print_function 语句)。

          try:
              py3 = eval('print')
          except SyntaxError:
              py3 = False
          
          if py3: exit('requires Python 2')
          ...
          

          它的工作原理是测试print 是否是一个内置函数,而不是一个语句,就像在 Python3 中一样。当它不是函数时,eval() 函数将引发异常,这意味着代码在 Python 3.0 之前的解释器上运行,具有上述警告。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-21
            • 1970-01-01
            相关资源
            最近更新 更多