Python 运行脚本时自动加载virtualenv

Python 运行脚本时自动加载virtualenv,python,virtualenv,Python,Virtualenv,我有一个python脚本,它需要来自virtualenv的依赖项。我想知道是否有什么方法可以将它添加到我的路径中,让它自动启动它的virtualenv,运行,然后返回到系统的python 我尝试过使用autoenv和.env,但这似乎并不完全符合我的要求。我还考虑过将沙邦改为指向virtualenv路径,但这似乎很脆弱。这有帮助吗 import site site.addsitedir('/path/to/virtualenv/lib/python2.7/site-packages/') 有两

我有一个python脚本,它需要来自virtualenv的依赖项。我想知道是否有什么方法可以将它添加到我的路径中,让它自动启动它的virtualenv,运行,然后返回到系统的python

我尝试过使用autoenv和
.env
,但这似乎并不完全符合我的要求。我还考虑过将沙邦改为指向virtualenv路径,但这似乎很脆弱。

这有帮助吗

import site
site.addsitedir('/path/to/virtualenv/lib/python2.7/site-packages/')

有两种方法可以做到这一点:

  • 将虚拟环境python的名称放入脚本的第一行。像这样

    #!/您的/virtual/env/path/bin/python

  • 将虚拟环境目录添加到sys.path。请注意,您需要导入sys库。像这样

    导入系统

    sys.path.append('/path/to/virtual/env/lib')

  • 如果使用第二个选项,则可能需要向sys.path(站点等)添加多个路径。获取它的最佳方法是运行虚拟环境python解释器并找出sys.path值。像这样:

    /your/virtual/env/bin/python
    
    Python blah blah blah
    
    > import sys
    > print sys.path
    [ 'blah', 'blah' , 'blah' ]
    

    将sys.path的值复制到上面的代码段中

    我认为最好的答案是创建一个简单的脚本并将其安装到VirtualNV中。然后,您可以直接使用脚本,或者创建符号链接,或者其他任何东西

    下面是一个例子:

    $ mkdir my-tool
    $ cd my-tool
    $ mkdir scripts
    $ touch setup.py
    $ mkdir scripts
    $ touch scripts/crunchy-frog
    $ chmod +x scripts/crunchy-frog
    
    松脆的青蛙

    #!/usr/bin/env python
    print("Constable Parrot ate one of those!")
    
    setup.py

    from setuptools import setup
    
    setup(name="my-cool-tool",
          scripts=['scripts/crunchy-frog'],
          )
    
    # -*- coding:utf-8 -*- 
    import os, site
    
    def locate_env(path, env_name):
        """search for a env directory name in each directory in the path"""
        if os.path.isdir(path + "/env"):
            env_26_path = '%s/%s/lib/python2.6/site-packages/' % (path, env_name)
            env_27_path = '%s/%s/lib/python2.7/site-packages/' % (path, env_name)
    
    
            if os.path.isdir(env_26_path):
                site.addsitedir(env_26_path)
                print "Virtualenv 2.6 founding"
            elif os.path.isdir(env_27_path):
                site.addsitedir(env_27_path)
                print "Virtualenv 2.7 founding"
        else:
            new_path, old_dir = os.path.split(path)
            if old_dir:
                locate_env(new_path, env_name)
            else:
                print "No envs found"
    
    # -*- coding:utf-8 -*-
    
    import os
    import script_autoenv
    script_autoenv.locate_env(os.path.realpath(__file__), 'env')
    
    import django
    print django.VERSION
    
    现在:

    当您安装脚本(通过
    setup.py install
    setup.py develope
    )时,它将用env python的shebang行替换
    脚本的第一行(您可以使用
    $head/path/to/my/env/bin/crunchy frog
    进行验证)。因此,无论何时运行该特定脚本,它都将使用virtualenv中的特定Python环境。

    如果直接从 virtualenv的bin/目录(例如path/to/env/bin/pip或 /path/to/env/bin/pythonscript.py)不需要激活

    因此,如果在virtualenv中调用python可执行文件,virtualenv将处于“活动”状态。因此,您可以创建如下脚本:

    #!/bin/bash
    
    PATH_TO_MY_VENV=/opt/django/ev_scraper/venv/bin
    
    $PATH_TO_MY_VENV/python -c 'import sys; print(sys.version_info)'
    python -c 'import sys; print(sys.version_info)'
    
    当我在我的系统上运行这个脚本时,对python的两个调用将打印您在下面看到的内容。(Python 3.2.3在我的virtualenv中,2.7.3是我的系统Python。)


    因此,当您调用
    $PATH\u TO\u MY\u VENV/python
    时,您在virtualenv中安装的任何库都将可用。对常规系统的调用
    python
    当然不会知道virtualenv中有什么内容。

    我以前遇到过这个问题,我编写了一个简单的脚本来递归查找virtualenv文件夹,只需导入和调用一个函数:

    脚本_autoenv.py

    from setuptools import setup
    
    setup(name="my-cool-tool",
          scripts=['scripts/crunchy-frog'],
          )
    
    # -*- coding:utf-8 -*- 
    import os, site
    
    def locate_env(path, env_name):
        """search for a env directory name in each directory in the path"""
        if os.path.isdir(path + "/env"):
            env_26_path = '%s/%s/lib/python2.6/site-packages/' % (path, env_name)
            env_27_path = '%s/%s/lib/python2.7/site-packages/' % (path, env_name)
    
    
            if os.path.isdir(env_26_path):
                site.addsitedir(env_26_path)
                print "Virtualenv 2.6 founding"
            elif os.path.isdir(env_27_path):
                site.addsitedir(env_27_path)
                print "Virtualenv 2.7 founding"
        else:
            new_path, old_dir = os.path.split(path)
            if old_dir:
                locate_env(new_path, env_name)
            else:
                print "No envs found"
    
    # -*- coding:utf-8 -*-
    
    import os
    import script_autoenv
    script_autoenv.locate_env(os.path.realpath(__file__), 'env')
    
    import django
    print django.VERSION
    
    您只需指定脚本目录和env name文件夹,脚本完成其余工作:

    test.py

    from setuptools import setup
    
    setup(name="my-cool-tool",
          scripts=['scripts/crunchy-frog'],
          )
    
    # -*- coding:utf-8 -*- 
    import os, site
    
    def locate_env(path, env_name):
        """search for a env directory name in each directory in the path"""
        if os.path.isdir(path + "/env"):
            env_26_path = '%s/%s/lib/python2.6/site-packages/' % (path, env_name)
            env_27_path = '%s/%s/lib/python2.7/site-packages/' % (path, env_name)
    
    
            if os.path.isdir(env_26_path):
                site.addsitedir(env_26_path)
                print "Virtualenv 2.6 founding"
            elif os.path.isdir(env_27_path):
                site.addsitedir(env_27_path)
                print "Virtualenv 2.7 founding"
        else:
            new_path, old_dir = os.path.split(path)
            if old_dir:
                locate_env(new_path, env_name)
            else:
                print "No envs found"
    
    # -*- coding:utf-8 -*-
    
    import os
    import script_autoenv
    script_autoenv.locate_env(os.path.realpath(__file__), 'env')
    
    import django
    print django.VERSION
    

    我希望它对您有用

    我很惊讶还没有人提到这一点,但这就是为什么virtualenv的bin目录中有一个名为
    activate\u this.py
    的文件。您可以将其传递到
    execfile()
    ,以更改当前运行的解释器的模块搜索路径

    # doing execfile() on this file will alter the current interpreter's
    # environment so you can import libraries in the virtualenv
    activate_this_file = "/path/to/virtualenv/bin/activate_this.py"
    
    execfile(activate_this_file, dict(__file__=activate_this_file))
    
    您可以将此文件放在脚本的顶部,以强制脚本始终在该virtualenv中运行。与修改hashbang不同,您可以通过以下操作使用相对路径:

    script_directory = os.path.dirname(os.path.abspath(__file__))
    activate_this_file = os.path.join(script_directory, '../../relative/path/to/env/bin/activate_this.py')
    

    答案可能是
    pipenv
    ()

    • 它将允许您执行以下操作:
    在python环境中使用指定的库运行
    main.py

    • 你可以在这里试试

    …也许这不是你想要的,但在重新创造它之前,也许值得一看

    一个非常简单的方法就是创建一个shell脚本,为您执行它。只需将
    path/to/venv/python path/to/script.py
    放在第一行,
    chmod+x
    新脚本并以这种方式执行。嗨,我正在Ubuntu 16.04上尝试在启动时运行Activitywatch。该程序在virtualenv上运行,必须使用命令
    source./venv/bin/activate
    ,然后运行
    aw qt
    。请您指导我如何在启动时运行此脚本。@AnoopD:假设aw qt是python脚本,您可以运行
    /path/to/venv/bin/python/path/to/aw qt
    我刚刚创建了一个文件
    activitywatch@anoopd.service
    /etc/systemd/system/
    中输入
    [Unit]Description=Activity Watch[Service]ExecStart=/home/anoopd/venv/bin/aw qt[Install]WantedBy=multi-user.target
    但这不起作用。@anoopd:你真的应该创建一个新问题,在评论部分很难正确回答。当然,请看一下我尝试了这个,但我遇到了一个错误“致命Python错误:Py_Initialize:无法获取区域设置编码模块NotFoundError:没有名为'encodings'的模块当前线程0x00007faa4f852700(首先是最近的调用):中止“它仍然找不到蟒蛇,你尝试了哪种方法?”?第一个还是第二个?你的sys.path是什么?在我的虚拟环境中,它使用Python 3.6.4非常有效。作为记录,我选择了第一个选项并键入了虚拟环境的Python路径,类似于:
    #!C:\Temp\Users\Python scripts\env\scripts\Python.exe
    然后转到powershell,然后我在powershell中执行脚本。这假设环境已经创建。在我处理的回购协议中,您只能得到一个现成的
    requirements.txt
    。用户需要运行venv。