【问题标题】:can one python script run both with python 2.x and python 3.x一个python脚本可以同时运行python 2.x和python 3.x吗
【发布时间】:2013-01-04 06:55:53
【问题描述】:

我有数千台服务器(linux),有些只有python 2.x,有些只有python 3.x,我想写一个脚本check.py可以像$./check.py一样在所有服务器上运行不使用 $python check.py 或 $python3 check.py,有什么办法吗?

我的问题是无论 Interpreter 是 python2.x 还是 python3.x,脚本 check.py 如何找到 Interpreter

【问题讨论】:

  • 当然...只要您使用两者通用的语言结构...
  • 问题是如何写第一行#/usr/bin/env python[2.x|3.x]来找到Interpreter
  • 为什么会有问题?只需运行python;在只有 2.x 或同时具有 2.x 和 3.x 的系统上,这将是 2.x;在只有 3.x 的系统上,它应该是 3.x。
  • 大声笑...我弄错了,你是对的,只需使用#/usr/bin/env python 就足够了,谢谢
  • @abarnert 请不要一概而论:至少在 Arch Linux 上是相反的:python == Python 3.x,python2 == Python 2.x。

标签: python python-3.x


【解决方案1】:

许多脚本可以在 2.x 和 3.x 上运行。 (我每天都有很多工作,我已经将各种开源库从仅 2.x 转换为双版本。)

一些事情让它变得更容易:

  • 对于 2.x 用户,需要 2.7,或至少 2.6+。否则,例如,您不能引发带参数的异常或将它们捕获到变量中,以及其他此类严重限制。
  • 对于 3.x 用户,需要 3.3+,或至少 3.2+。在 3.2 或 3.3 中,大部分无缘无故的不兼容(例如 u 前缀被删除)都被逆转了。
  • 使用six 库。
  • 使用__future__ 语句。
  • 始终清楚您的意思是bytes(始终为 8 位)、unicode(如果您想要 8 位则必须编码)或 str(无论大多数 stdlib API 所期望的) ,以及encodedecode(视需要而定)。
  • 定期在您的代码上运行2to3。 (但不要盲目地做它所说的一切。例如,如果您使用 d.keys()map(f, l),因为您不在乎是否返回 list,您会收到警告,因为2to3 不知道你不在乎。)

或者,与其尝试编写在两者上运行的代码,不如编写在 2.x 上运行但可以由 2to3 自动转换为运行 3.x 代码的代码,并将其作为安装过程的一部分(在setup.pyif sys.version_info >= (3, 0): 中执行2to3 步骤)。

从您的编辑看来,您最关心的是在#!线。为此:

/usr/bin/env python

这不能保证有效,但 env 首先不能保证有效……您可以相信:

  • 在平台/发行版仅提供 2.x 的任何系统上,python 是 Python 2。
  • 在平台/发行版同时提供两者的任何系统上,python 是 Python 2。
  • 在平台/发行版仅提供 3.x(目前非常罕见,但可能最终会更常见)的任何系统上,python 是 Python 3。

但是:

  • 在平台不提供的系统上,如果管理员只安装了 3.x,它可能(截至 2013 年初)以@987654343 的形式提供@。您对此无能为力。

如果最后一个问题很严重,您可以通过添加一个用 sh 编写的启动器脚本来解决它,该脚本尝试python,如果失败则尝试python3

这样做的好方法是将启动器脚本本身指定为 Python 脚本中的 shebang 解释器。 Linux 可以处理这个问题,但它是可配置的,并且至少有一些发行版默认禁用它——而大多数其他 *nix 系统无法做到。

如果这不起作用,下一个最佳选择是让用户运行启动器脚本——也就是说,告诉他们执行./check.sh 而不是./check.py,然后check.sh 找出正确的 Python 解释器并为用户运行$python ./check.py

如果你想变得非常棘手,你甚至可以将 Python 脚本作为一个 heredoc 嵌入到 shell 脚本中,这样你只需要分发一个文件。他们运行./check.sh,它会找到正确的 Python 并在 heredoc 上运行它。

【讨论】:

  • thx,我只是想这样做,但这不是我的问题,我认为用python3运行只能使用#!/usr/bin/env python3,一个错误
  • @xielingyun:大多数流行的平台要么只安装 2.x,要么同时安装两者。但是有些系统两者都没有——而且,正如我所说,如果管理员只安装 3.x(特别是如果他从 python.org 安装而不是使用发行版包),它可能无法作为 @987654351 使用@。这对你来说是个严重的问题吗?如果是这样,您到底在处理什么平台?
  • @xielingyun:我在该案例的一些一般帮助下编辑了答案,但正如我所说,它不适用于所有平台。
  • :有问题,我的平台是linux(rhel 4.x/5.x/6.x, centos 4.x/5.x/6.x),如果不行可以作为python 使用并且脚本无法运行,工人对python一无所知,所以脚本可以作为./check.py 运行
  • 感谢您的帮助,使用 shell 脚本包装 mybe 最好的想法
【解决方案2】:

考虑到 Python 3.x 并不完全向后兼容 Python 2.x,您必须确保脚本与这两个版本兼容。这可以在2to3 工具的帮助下完成,但最终可能意味着运行两个不同的 Python 脚本。

【讨论】:

    【解决方案3】:

    一般情况下,不会;许多 Python 2 脚本无法在 Python 3 上运行,反之亦然。它们是两种不同的语言。

    话虽如此,如果你小心的话,你可以编写一个在这两种情况下都能正常运行的脚本。一些作者特别注意确保他们的脚本在两个版本之间兼容,通常使用额外的工具,如 six 库(名称是双关语;您可以通过将“二乘以三”或“三乘二”)。

    然而,现在是 2020 年,Python 2 正式死亡。许多以前在 Python 2 仍受支持的情况下努力维护它的兼容性的维护者现在会如释重负,并且通常非常乐意继续使用它。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 2010-09-25
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-05
      相关资源
      最近更新 更多