简体   繁体   English

一个python脚本可以同时运行python 2.x和python 3.x吗

[英]can one python script run both with python 2.x and python 3.x

i have thousands of servers(linux), some only has python 2.x and some only has python 3.x, i want to write one script check.py can run on all servers just as $./check.py without use $python check.py or $python3 check.py, is there any way to do this?我有数千台服务器(linux),有些只有 python 2.x,有些只有 python 3.x,我想写一个脚本 check.py 可以在所有服务器上运行,就像 $./check.py 不使用 $ python check.py 或 $python3 check.py,有没有办法做到这一点?

my question is how the script check.py find the Interpreter no matter the Interpreter is python2.x and python3.x我的问题是无论解释器是 python2.x 还是 python3.x,脚本 check.py 如何找到解释器

Many scripts can run on both 2.x and 3.x.许多脚本可以在 2.x 和 3.x 上运行。 (I've got a bunch I work on on a daily basis, and I've converted various open source libraries from 2.x-only to dual-version.) (我每天都有很多工作要做,而且我已经将各种开源库从 2.x-only 转换为双版本。)

A few things make it much easier:有几件事使它变得更容易:

  • Require 2.7, or at least 2.6+, for 2.x users. 2.x 用户需要 2.7 或至少 2.6+。 Otherwise, for example, you cannot raise and exceptions with parameters or catch them into variables, and other such severe limitations.否则,例如,您不能使用参数引发异常或将它们捕获到变量中,以及其他此类严重限制。
  • Require 3.3+, or at least 3.2+, for 3.x users. 3.x 用户需要 3.3+,或至少 3.2+。 Most of the gratuitous incompatibilities (like the u prefix being taken away) were reversed in 3.2 or 3.3.大多数无缘无故的不兼容性(如u前缀被取消)在 3.2 或 3.3 中被逆转。
  • Use the six library.使用库。
  • Use __future__ statements.使用__future__语句。
  • Always be clear in your head about whether you mean bytes (always 8-bit), unicode (must encode if you want 8-bit), or str (whatever most of the stdlib APIs expect), and encode and decode as necessary.始终清楚您的意思是bytes (始终为 8 位)、 unicode (如果您想要 8 位,则必须进行编码)还是str (大多数 stdlib API 所期望的),并根据需要encodedecode
  • Regularly run 2to3 on your code.定期对您的代码运行2to3 (But don't blindly do everything it says. If, eg, you're using d.keys() or map(f, l) because you don't care whether you get back a list or not, you'll get a warning, because 2to3 doesn't know you don't care.) (但不要盲目地做它所说的一切。如果,例如,你使用d.keys()map(f, l)因为你不在乎你是否得到一个list ,你会得到警告,因为2to3不知道您不在乎。)

Alternatively, instead of trying to write code that runs on both, write code that runs on 2.x, but can be automatically transformed by 2to3 into running 3.x code, and make that part of your installation process (in setup.py , if sys.version_info >= (3, 0): do the 2to3 step).或者,不要尝试编写在两者上运行的代码,而是编写在 2.x 上运行的代码,但可以由2to3自动2to3为运行 3.x 代码,并将该部分作为安装过程的一部分(在setup.pyif sys.version_info >= (3, 0):执行2to3步骤)。

From your edit, it sounds like you're mostly concerned with what to put in the #!从您的编辑来看,您似乎最关心的是在 #! line.线。 For that:为了那个原因:

/usr/bin/env python

This isn't guaranteed to work—but then env isn't guaranteed to work in the first-place… You can count on the fact that:这不能保证工作 - 但是首先不能保证env工作......你可以指望这样一个事实:

  • On just about any system where the platform/distro supplies only 2.x, python is Python 2.在平台/发行版仅提供 2.x 的任何系统上, python是 Python 2。
  • On just about any system where the platform/distro supplies both, python is Python 2.在平台/发行版提供两者的几乎任何系统上, python是 Python 2。
  • On just about any system where the platform/distro supplies only 3.x (which currently is very rare, but will presumably eventually be more common), python is Python 3.在平台/发行版仅提供 3.x 的几乎所有系统上(目前非常罕见,但可能最终会更常见), python是 Python 3。

However:然而:

  • On a system where the platform supplies neither , if the admin only installed 3.x, it will likely (as of early 2013) not be available as python .在平台两者都不提供的系统上,如果管理员只安装了 3.x,它很可能(截至 2013 年初)不能作为python There's not much you can do about this one.关于这一点,你无能为力。

If the last one is a serious problem, you can work around it by adding a launcher script, written in sh, that tries python and then tries python3 if that fails.如果最后一个是一个严重的问题,您可以通过添加一个用 sh 编写的启动程序脚本来解决它,该脚本尝试python ,如果失败则尝试python3

The nice way to do this is to specify the launcher script itself as the shebang interpreter in your Python script.这样做的好方法是将启动程序脚本本身指定为 Python 脚本中的 shebang 解释器。 Linux can handle this, but it's configurable, and at least some distros disable it by default—and most other *nix systems can't do it. Linux 可以处理这个问题,但它是可配置的,至少一些发行版默认禁用它——而大多数其他 *nix 系统不能这样做。

If that doesn't work, the next best option is to make the user run the launcher script—that is, tell them to do ./check.sh instead of ./check.py , and check.sh figures out the right Python interpreter and runs $python ./check.py for the user.如果这不起作用,下一个最佳选择是让用户运行启动程序脚本——也就是说,告诉他们执行./check.sh而不是./check.py ,然后check.sh找出正确的 Python解释器并为用户运行$python ./check.py

If you want to get really tricky, you could even embed the Python script as a heredoc inside the shell script, so you only need to distribute one file.如果你想变得非常棘手,你甚至可以将 Python 脚本作为一个 heredoc 嵌入到 shell 脚本中,这样你只需要分发一个文件。 They run ./check.sh , and it finds the right Python and runs it on the heredoc.他们运行./check.sh ,它会找到正确的 Python 并在 heredoc 上运行它。

Considering that Python 3.x is not entirely backwards compatible with Python 2.x, you would have to ensure that the script was compatible with both versions.考虑到 Python 3.x 并不完全向后兼容 Python 2.x,您必须确保脚本与两个版本兼容。 This can be done with some help from the 2to3 tool, but may ultimately mean running two distinct Python scripts.这可以在2to3工具的帮助下完成,但最终可能意味着运行两个不同的 Python 脚本。

In the general case, no;在一般情况下,没有; many Python 2 scripts will not run on Python 3, and vice versa.许多 Python 2 脚本不能在 Python 3 上运行,反之亦然。 They are two different languages.它们是两种不同的语言。

Having said that, if you are careful, you can write a script which will run correctly under both.话虽如此,如果您小心,您可以编写一个脚本,该脚本将在两者下都正确运行。 Some authors take extra care to make sure their scripts will be compatible across both versions, commonly using additional tools like the six library (the name is a pun; you can get to "six" by multiplying "two by three" or "three by two").一些作者特别注意确保他们的脚本在两个版本中兼容,通常使用额外的工具,如six库(名称是双关语;你可以通过将“二乘以三”或“三乘以二”)。

However, it is now 2020, and Python 2 is officially dead.然而,现在是 2020 年,Python 2 正式死亡。 Many maintainers who previously strove to maintain Python 2 compatibility while it was still supported will now be relieved and often outright happy to pull the plug on it going forward.许多以前在 Python 2 仍然受支持的情况下努力保持其兼容性的维护人员现在松了一口气,并且通常非常乐意在未来拔掉插头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM