如何在Python3.11中通过subprocess.run运行Python2.7脚本?
问题
我司有一个基于Python2.7编写的install.py脚本,我用Python3.11编写脚本时,尝试通过subprocess.run(f"python2.7 {path}/install.py", check=True, shell=True)调用它,但出现语法错误:
print "Out>", serialized[:300] + (["...", ""][len(serialized) < 80]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
这个错误说明脚本实际是用Python3.11运行的,install.py头部虽然有#!/usr/bin/env python2.7但不起作用。查看系统版本发现python2.7 --version返回Python 3.11.4,而且无法通过sudo apt install python2.7安装Python2.7。
我自己通过asdf仓库在本地解决了问题,添加命令subprocess.run(f"echo python 2.7.18 > {new_path}/.tool-versions")生成本地配置文件,但asdf不是公司Linux环境的标配,很难推广;用Docker方案又太冗余。
现咨询两个问题:
- 当前场景下如何用Python2.7运行代码?
- 有无其他方法在Python3.x环境中运行Python2.7脚本?
解决方案
问题1:当前场景下如何用Python2.7运行代码?
- 指定Python2.7绝对路径:先确认公司服务器上是否存在预安装的Python2.7二进制文件(比如
/usr/local/bin/python2.7或运维统一部署的路径),直接在subprocess.run中用绝对路径调用,示例:subprocess.run(f"/usr/local/bin/python2.7 {path}/install.py", check=True, shell=True)。如果没有,可申请权限在公共目录(如/opt/python2.7)编译安装Python2.7,步骤为:下载2.7.18源码包 → 执行./configure --prefix=/opt/python2.7→ 编译安装make && make install,后续统一用该路径调用。 - 用pyenv统一管理版本:如果团队接受度更高,可在公司环境统一安装pyenv,通过
pyenv local 2.7.18指定目标目录的Python版本,调用时用pyenv exec python {path}/install.py,避免路径冲突问题。 - 直接部署Python2.7二进制包:下载Python2.7的预编译二进制包,解压到公司公共目录,无需编译,直接用解压后的
bin/python2.7路径调用脚本。
问题2:有无其他方法在Python3.x环境中运行Python2.7脚本?
- 用2to3工具转换脚本:使用官方的
2to3工具将install.py转换为Python3兼容版本,它能自动处理print语句转函数、Unicode编码等大部分语法差异。转换后直接用Python3运行,注意测试功能是否正常,排查个别自定义语法或第三方库的兼容问题。 - 借助python-future做兼容改造:在Python3环境安装
python-future库,修改install.py头部添加from __future__ import print_function, unicode_literals等兼容导入,逐步替换脚本中的Python2特有语法,让脚本同时兼容Python2和3,适合需要逐步迁移的场景。 - 用pypy2替代运行:如果允许安装pypy2(Python2的JIT实现),可直接解压pypy2的二进制包使用,调用时用
pypy2 {path}/install.py,部署比编译Python2.7更简单。
内容的提问来源于stack exchange,提问作者Saar Katz
相关产品推荐
相关产品推荐

