如何在使用子进程时避免加载错误的库。Popen() 从 python 脚本运行 venv?

How to avoid loading wrong libraries when using a subprocess.Popen() from a python script to run a venv?

提问人:Srijeet 提问时间:11/28/2022 更新时间:12/8/2022 访问量:140

问:

我想从另一个使用 python3.6 的应用程序的子进程调用中使用 venv python~3.9 运行脚本。但是,导入的库是错误的,并且来自 3.6 版本的站点包。如何修改子进程调用以加载正确的库,即从 venv(3.9 版本)

p = Popen([process_name, parameters_l], stdin=PIPE, stdout=PIPE, stderr=PIPE)

我尝试使用 cwd 并通过 os.chdir 更改工作目录,但这似乎不起作用。此外,我尝试从 venv 运行 activat.bat,但问题仍然存在。

Python 子进程 加载库

评论

0赞 Constantin Hong 11/28/2022
你会输入你的shell(或终端)吗?请在这里发布。which python
0赞 Srijeet 11/30/2022
所以当然python调用是针对3.9的,即sys.executable print是:D:/Test/python/venv/Scripts/python.exe。但是,它无法正确加载库:文件“D:\Core\build\Slicer\lib\Python\Lib\site-packages\numpy_config_.py”,第 13 行,在 <module> os.add_dll_directory(extra_dll_dir) AttributeError 中:模块“os”没有属性“add_dll_directory”
0赞 mx0 12/1/2022
@Srijeet 您是否正在尝试运行 3D 切片器应用程序?
1赞 Srijeet 12/2/2022
@mx0,是的,我正在尝试从 3D 切片器 python 编写 python 脚本

答:

0赞 Constantin Hong 11/28/2022 #1

这是我的例子。

example.py

此代码显示您运行的 Python 版本。

import sys 
print("version {}".format(sys.version))

traverse_python.sh

此代码遍历各种 Python 版本,以显示运行代码的版本。

您可以将 更改为要使用的 Python 版本。process_name

import time
import subprocess, os

pythoninterpretor = ['/usr/local/bin/python3.10', '/usr/local/bin/python3.11']

for i in pythoninterpretor:
    process_name = i
    parameters = 'example.py'
    p = subprocess.Popen([process_name, parameters])
    time.sleep(10)

我的结果

仅供参考,即使您在脚本中明确使用shebang中的另一个python版本,结果也不会改变。

version 3.10.8 (main, Oct 13 2022, 10:17:43) [Clang 14.0.0 (clang-1400.0.29.102)]
version 3.11.0 (main, Oct 25 2022, 14:13:24) [Clang 14.0.0 (clang-1400.0.29.202)]

就您而言,

python_interpretor = '/absolute/path/env/python3.9'
p = Popen([python_interpretor, process_name, parameters_l], stdin=PIPE, stdout=PIPE, stderr=PIPE)

您需要替换为理想版本的路径。/absolute/path/env/python3.9

1赞 Srijeet 12/8/2022 #2

为了解决这个问题,我必须获取当前环境并删除一些变量,例如:

env = os.environ.copy()
del env["PYTHONPATH"]

Popen([process_name, parameters_l], env=env)

最后,在子进程调用中使用 new env 作为参数。如果有人面临类似的情况,希望它会有所帮助。