首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在具有自己路径的不同python可执行文件下生成multiprocessing.Process

在具有自己路径的不同python可执行文件下生成multiprocessing.Process
EN

Stack Overflow用户
提问于 2016-09-07 22:31:18
回答 1查看 2K关注 0票数 11

我有两个版本的Python (实际上是两个conda环境)

代码语言:javascript
复制
/path/to/bin-1/python
/path/to/bin-2/python

在一个版本的python中,我想使用类似于multiprocessing.Process对象的东西启动一个在另一个版本中运行的函数。事实证明,使用set_executable方法可以做到这一点:

代码语言:javascript
复制
ctx = multiprocess.get_context('spawn')
ctx.set_executable('/path/to/bin-2/python')

事实上,我们可以看到这确实是使用该可执行文件启动的:

代码语言:javascript
复制
def f(q):
    import sys
    q.put(sys.executable)

if __name__ == '__main__':
    import multiprocessing
    ctx = multiprocessing.get_context('spawn')
    ctx.set_executable('/path/to/bin-2/python')
    q = ctx.Queue()
    proc = ctx.Process(target=f, args=(q,))
    proc.start()
    print(q.get())

$ python foo.py
/path/to/bin-2/python

然而,路径是错误的

然而,当我使用sys.path而不是sys.executable做同样的事情时,我发现托管python进程的sys.path被打印出来,而不是我直接运行/path/to/bin-2/python -c "import sys; print(sys.path)"时找到的sys.path。

如果我使用fork,我就习惯了这种事情。我本以为'spawn'会像我从shell进入python解释器一样。

问题

在我从shell启动的环境中,是否可以使用多处理库来运行函数和使用另一个Python可执行文件中的队列?

更广泛地说,sys.path是如何填充的,以这种方式使用多处理与直接启动解释器有什么不同?

EN

回答 1

Stack Overflow用户

发布于 2018-10-24 23:06:57

我遇到了同样的问题。我的系统范围的Python可执行文件在/path/to/bin-1/python上,我使用virtualenv创建了一个虚拟环境,其中包含/path/to/bin-2/python上的另一个Python可执行文件。为了为/path/to/bin-2/python所需的衍生进程设置正确的路径/环境,我最终将代码从virtualenv文件夹中的activate_this.py复制到f(q)

代码语言:javascript
复制
def f(q):
    import sys, os

    def active_virtualenv(exec_path):
        """
        copy virtualenv's activate_this.py
        exec_path: the python.exe path from sys.executable
        """
        # set env. var. PATH
        old_os_path = os.environ.get('PATH', '')
        os.environ['PATH'] = os.path.dirname(os.path.abspath(exec_path)) + os.pathsep + old_os_path
        base = os.path.dirname(os.path.dirname(os.path.abspath(exec_path)))
        # site-pachages path
        if sys.platform == 'win32':
            site_packages = os.path.join(base, 'Lib', 'site-packages')
        else:
            site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
        # modify sys.path
        prev_sys_path = list(sys.path)
        import site
        site.addsitedir(site_packages)
        sys.real_prefix = sys.prefix
        sys.prefix = base
        # Move the added items to the front of the path:
        new_sys_path = []
        for item in list(sys.path):
            if item not in prev_sys_path:
                new_sys_path.append(item)
                sys.path.remove(item)
        sys.path[:0] = new_sys_path
        return None

    active_virtualenv(sys.executable)
    q.put(sys.executable)
    # check some unique package in this env.
    import special_package
    print "package version: {}".format(special_package.__version__)


if __name__ == '__main__':
    import multiprocessing
    multiprocessing.set_executable('/path/to/bin-2/python')
    q = multiprocessing.Queue()
    proc = multiprocessing.Process(target=f, args=(q,))
    proc.start()
    proc.join()
    print(q.get())

标准:

代码语言:javascript
复制
$ python foo.py
/path/to/bin-2/python
package version: unique_version_only_in_virtualenv

有一件事我不太确定,那就是sysosactive_virtualenv()之前是import的,这意味着它们来自系统范围的Python env。但我在f(q)中需要的其他包来自虚拟环境。也许在切换环境后重新import它们是值得的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39372708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档