Python multiprocessing.Process 使用 virtualenv
Python multiprocessing.Process to use virtualenv
我是运行一个使用virtualenv的程序。但是这里生成的 multiprocessing.Process 默认使用系统 python。我如何强制它使用 virtualenv python.
import os
from multiprocessing import Process
def function1():
# do_something_here
p = Process(func2(), args=(param,))
p.start()
return something
def func2(param):
os.system("which python")
这里打印“/usr/bin/python”。但我需要它来使用 virtualenv python。
使用 sudo venv/bin/python
,您 effectively activated virtualenv 通过直接在 virtualenv 中使用 python 可执行文件。
multiprocessing.Process
使用 fork()
生成子进程,不使用 exec()
,它使用与父进程完全相同的 python 可执行文件。
您可以通过以下方式确认 python 可执行文件正在使用中:
>>> import sys
>>> print(sys.executable)
/Users/georgexsh/workspace/tmp/venv/bin/python
>>> print(sys.exec_prefix)
/Users/georgexsh/workspace/tmp/venv/bin/..
不要使用which
来确定运行宁python可执行文件路径。 which
,作为一个Bash命令,在$PATH
的每个元素中搜索一个包含名为"python"的可执行文件的目录,就像你直接使用virtualenv的python一样,不是 运行 它的 shell 首先激活脚本,$PATH
没有用 virtualenv 打补丁,因此,shell 命令 which python
会输出系统路径 python可执行文件。
其实在python层,$PATH
是无关紧要的,打补丁$PATH
是为了方便在Bash层调用python只需键入 "python" 即可在 virtualenv 路径中执行可执行文件,而不是键入完整路径,最重要的是调用哪个 python 可执行文件,而不是如何调用它。
您的问题在这里(已复制您的评论):
@georgexsh I was running it using sudo. By default if you use sudo
then it will use system python. So, I have used "sudo venv/bin/python
main.py" to run the program. Even though I am using venv's python here
it returns "/usr/bin/python" for "os.system('which python')". I don't
understand this behaviour
基本上,你在这里解释的是你的 virtualenv 没有激活的地方。
当您激活 virtualenv (. venv/bin/activate)
时,激活脚本将更改您的环境,以便您的 PYTHONPATH
是正确的,并且首先在虚拟环境中搜索(并找到)Python 可执行文件环境目录。这就是 virtualenv 所做的。
通过仅从 virtualenv 目录执行 Python 二进制文件,您的环境并未设置为虚拟环境,因此对 Python 的任何后续调用都使用您的默认路径 - 因为 virtualenv 不存在覆盖它。
当您执行 sudo 时,会创建一个新的 process/shell,它不会继承您的虚拟环境。您也许可以使用 sudo -E
来传递环境,但这取决于您的 sudo。应该在每个环境中工作的防弹版本是执行 shell 首先激活 virtualenv 然后执行你的脚本。像这样:
sudo -- bash -c ". /home/test/mytest/bin/activate; which python"
这将以 root 身份执行 bash shell,然后激活虚拟环境,最后告诉您它使用哪个 python。只需使用您的虚拟环境路径修改上述命令,它甚至可能会起作用。
如果您的系统是共享的,请记住,从安全角度来看,允许您的普通用户这样做是一件可怕的事情。如果您为您的普通用户创建一个无密码的 sudo 来执行此操作,则只需稍作调整即可为他们提供 root 访问权限。如果是你自己的系统,反正要求是知道root密码,那也没关系。
我是运行一个使用virtualenv的程序。但是这里生成的 multiprocessing.Process 默认使用系统 python。我如何强制它使用 virtualenv python.
import os
from multiprocessing import Process
def function1():
# do_something_here
p = Process(func2(), args=(param,))
p.start()
return something
def func2(param):
os.system("which python")
这里打印“/usr/bin/python”。但我需要它来使用 virtualenv python。
使用 sudo venv/bin/python
,您 effectively activated virtualenv 通过直接在 virtualenv 中使用 python 可执行文件。
multiprocessing.Process
使用 fork()
生成子进程,不使用 exec()
,它使用与父进程完全相同的 python 可执行文件。
您可以通过以下方式确认 python 可执行文件正在使用中:
>>> import sys
>>> print(sys.executable)
/Users/georgexsh/workspace/tmp/venv/bin/python
>>> print(sys.exec_prefix)
/Users/georgexsh/workspace/tmp/venv/bin/..
不要使用which
来确定运行宁python可执行文件路径。 which
,作为一个Bash命令,在$PATH
的每个元素中搜索一个包含名为"python"的可执行文件的目录,就像你直接使用virtualenv的python一样,不是 运行 它的 shell 首先激活脚本,$PATH
没有用 virtualenv 打补丁,因此,shell 命令 which python
会输出系统路径 python可执行文件。
其实在python层,$PATH
是无关紧要的,打补丁$PATH
是为了方便在Bash层调用python只需键入 "python" 即可在 virtualenv 路径中执行可执行文件,而不是键入完整路径,最重要的是调用哪个 python 可执行文件,而不是如何调用它。
您的问题在这里(已复制您的评论):
@georgexsh I was running it using sudo. By default if you use sudo then it will use system python. So, I have used "sudo venv/bin/python main.py" to run the program. Even though I am using venv's python here it returns "/usr/bin/python" for "os.system('which python')". I don't understand this behaviour
基本上,你在这里解释的是你的 virtualenv 没有激活的地方。
当您激活 virtualenv (. venv/bin/activate)
时,激活脚本将更改您的环境,以便您的 PYTHONPATH
是正确的,并且首先在虚拟环境中搜索(并找到)Python 可执行文件环境目录。这就是 virtualenv 所做的。
通过仅从 virtualenv 目录执行 Python 二进制文件,您的环境并未设置为虚拟环境,因此对 Python 的任何后续调用都使用您的默认路径 - 因为 virtualenv 不存在覆盖它。
当您执行 sudo 时,会创建一个新的 process/shell,它不会继承您的虚拟环境。您也许可以使用 sudo -E
来传递环境,但这取决于您的 sudo。应该在每个环境中工作的防弹版本是执行 shell 首先激活 virtualenv 然后执行你的脚本。像这样:
sudo -- bash -c ". /home/test/mytest/bin/activate; which python"
这将以 root 身份执行 bash shell,然后激活虚拟环境,最后告诉您它使用哪个 python。只需使用您的虚拟环境路径修改上述命令,它甚至可能会起作用。
如果您的系统是共享的,请记住,从安全角度来看,允许您的普通用户这样做是一件可怕的事情。如果您为您的普通用户创建一个无密码的 sudo 来执行此操作,则只需稍作调整即可为他们提供 root 访问权限。如果是你自己的系统,反正要求是知道root密码,那也没关系。