【问题标题】:Python subproccess.run isn't working with PyinstallerPython subproccess.run 不适用于 Pyinstaller
【发布时间】:2021-04-04 08:48:56
【问题描述】:

考虑以下名为 test.py 的 python (3.9) 脚本:

import sys
import os
import subprocess
from pathlib import Path

# This is for pyinstaller (as main_dir = sys.path[0] won't work)
if getattr(sys, 'frozen', False):
    main_dir = os.path.dirname(sys.executable)
else:
    main_dir = os.path.dirname(os.path.abspath(__file__))

processes_dir = Path(main_dir, "processes")
outfile = Path(main_dir, "output.txt")

# Initialize the output text file
with open(outfile, 'w') as f:
    f.write('')

# This calls A1.py (see below)
result = subprocess.run([sys.executable, Path(processes_dir, "A1.py")], input="1\n2", capture_output=True, text=True)

# If an error is raised, it's written to output.txt; stdout is written to output.txt
if result.stderr:
    with open(outfile, 'a') as f:
        f.write("{0}\n\n".format(result.stderr))
else:
    with open(outfile, 'a') as f:
        f.write("{0}\n\n".format(result.stdout))

subprocess.run 调用以下简单脚本:

x1 = int(input())
x2 = int(input())
print(x1+x2)

这运行得很好。我正在尝试研究如何使用 Pyinstaller 将其转换为可执行文件 (.exe)。在相应的目录中,我运行:

pyinstaller --onefile test.py

这会成功构建 test.exe。当我运行 test.exe(从 cmd 或双击文件)时,它打开时没有错误,产生一个空的 output.txt,然后只是无限期地挂起。看来 subprocess.run 无法与 pyinstaller 一起正常工作。有什么想法/建议可以让 test.exe 与 pyinstaller 一起使用?

【问题讨论】:

  • 你从PyPi安装了pyinstaller吗?如果是这样,请尝试卸载它并从 github pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip 安装它
  • 根据 pyinstaller 文档,sys.executable 不像普通 Python 代码那样是 Python 解释器,因此使用它来运行 Python 脚本可能无法如您所愿。尝试打印它,看看它是什么。 pyinstaller.readthedocs.io/en/stable/runtime-information.html
  • @IceBear 是的,我使用pip install pyinstallerPyPi 安装了它。我相信它与github上提供的安装相同。
  • @barny 它打印 C:\Users\Daniel\Desktop\Pyinstaller_test\test.exe 这确实是 test.exe 的位置,所以这似乎是问题所在。 PyInstaller 应该捆绑一个 python 应用程序(以及所有必需的依赖项),那么我如何指导 test.exe 调用这个捆绑的 python?我可能可以将其指向我的 python 安装,但这首先破坏了将其捆绑为 exe 的全部目的,因为我打算与没有安装 python 的用户共享它。
  • 你的代码可以导入python代码并从中执行一些东西,或者你可以评估它来执行一些东西。

标签: python python-3.x subprocess pyinstaller


【解决方案1】:

这里发生的情况是,当脚本未编译时,sys.executable 返回 python 可执行文件(C:\Users\randomuser\AppData\Local\Programs\Python38),但在编译代码时,sys.executable 返回 .你已经制作的exe文件。所以,你的 .exe 文件会调用自己,无限次调用自己,哈哈。

您可以通过两种不同(简单)的方式解决此问题:

  1. (如果您想分发 exe 文件,则不推荐,因为它依赖于 python 安装):
    sys.executable 替换为'python'。这将确保脚本使用 Python 执行,而不是使用您自己的 .exe 文件(如果已编译):

     result = subprocess.run(['python', Path(processes_dir, "A1.py")], input="1\n2", capture_output=True, text=True)
    
  2. 您可以导入A1.py 脚本(确保脚本与可执行文件位于同一文件夹中,并将主要代码放在名为 main 的函数中,以字符串形式返回结果):

然后,你就可以运行import A1,并调用运行A1.main()的主程序:

import sys
import os
import subprocess
import A1
from pathlib import Path

# This is for pyinstaller (as main_dir = sys.path[0] won't work)
if getattr(sys, 'frozen', False):
    main_dir = os.path.dirname(sys.executable)
else:
    main_dir = os.path.dirname(os.path.abspath(__file__))

processes_dir = Path(main_dir, "processes")
outfile = Path(main_dir, "output.txt")

# Initialize the output text file
with open(outfile, 'w') as f:
    f.write('')

# This calls A1.py (see below)
result = A1.main()

# The output is written into output.txt.

with open(outfile, 'a') as f:
    f.write("{0}\n\n".format(result))
          

您可以考虑使用 try-except 子句和 traceback 模块捕获错误回溯

pyinstaller 命令应该是:pyinstaller --onefile test.py --add-data "A1.py;."

【讨论】:

    猜你喜欢
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-20
    • 1970-01-01
    相关资源
    最近更新 更多