是否可以确定当前脚本是否在virtualenv环境中运行?
AFAIK最可靠的检查方法(以及在virtualenv和pip中内部使用的方式)是检查是否存在sys.real_prefix
:
import sys if hasattr(sys, 'real_prefix'): #...
里面的virtualenv,sys.prefix
指向的virtualenv目录,并sys.real_prefix
指向系统的Python(通常的"真正的"前缀/usr
或/usr/local
或类似).
在virtualenv之外,sys.real_prefix
不应该存在.
使用VIRTUAL_ENV
环境变量是不可靠的.它由virtualenv activate
shell脚本设置,但是通过直接运行virtualenv bin/
(或Scripts
)目录中的可执行文件,可以在不激活的情况下使用virtualenv ,在这种情况下$VIRTUAL_ENV
不会设置.
尝试使用pip -V
(注意资本V)
如果您正在运行虚拟环境.它将显示env.的位置路径.
这是Carl Meyer接受的答案的改进.它适用于Python 3和2的virtualenv以及Python 3中的venv模块:
import sys def is_venv(): return (hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
检查sys.real_prefix
涵盖了virtualenv,非空的平等sys.base_prefix
与sys.prefix
封面venv.
考虑使用如下函数的脚本:
if is_venv(): print('inside virtualenv or venv') else: print('outside virtualenv or venv')
以下调用:
$ python2 test.py outside virtualenv or venv $ python3 test.py outside virtualenv or venv $ python2 -m virtualenv virtualenv2 ... $ . virtualenv2/bin/activate (virtualenv2) $ python test.py inside virtualenv or venv (virtualenv2) $ deactivate $ python3 -m virtualenv virtualenv3 ... $ . virtualenv3/bin/activate (virtualenv3) $ python test.py inside virtualenv or venv (virtualenv3) $ deactivate $ python3 -m venv venv3 $ . venv3/bin/activate (venv3) $ python test.py inside virtualenv or venv (venv3) $ deactivate
使用$ VIRTUAL_ENV变量确实会检查我们是否在虚拟环境中,但问题可能在于当我们离开virtualenv时无法清除此变量的deactivate函数.
根据http://www.python.org/dev/peps/pep-0405/#specification上的virtualenv pep,您可以使用sys.prefix而不是os.environ ['VIRTUAL_ENV'].
sys.real_prefix在我的virtualenv中不存在,与sys.base_prefix相同.
要检查您的Virtualenv内部是否存在:
import os if os.getenv('VIRTUAL_ENV'): print('Using Virtualenv') else: print('Not using Virtualenv')
您还可以获取有关您的环境的更多数据:
import sys import os print(f'Python Executable: {sys.executable}') print(f'Python Version: {sys.version}') print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
您可以which python
查看虚拟环境中是否指向该环境。
更新于2019年11月(附加)。
我通常使用几个Anaconda安装的虚拟环境(venv)。此代码片段/示例使您可以确定是否处于venv(或系统环境)中,并且还需要脚本使用特定的venv。
添加到Python脚本(代码段):
# ---------------------------------------------------------------------------- # Want script to run in Python 3.5 (has required installed OpenCV, imutils, ... packages): import os # First, see if we are in a conda venv { py27: Python 2.7 | py35: Python 3.5 | tf: TensorFlow | thee : Theano } try: os.environ["CONDA_DEFAULT_ENV"] except KeyError: print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n") exit() # If we are in a conda venv, require the p3 venv: if os.environ['CONDA_DEFAULT_ENV'] != "py35": print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n") exit() # See also: # Python: Determine if running inside virtualenv # http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv # [ ... SNIP! ... ]
例:
$ p2 [Anaconda Python 2.7 venv (source activate py27)] (py27) $ python webcam_.py Please set the py35 { p3 | Python 3.5 } environment! (py27) $ p3 [Anaconda Python 3.5 venv (source activate py35)] (py35) $ python webcam.py -n50 current env: py35 processing (live): found 2 faces and 4 eyes in this frame threaded OpenCV implementation num_frames: 50 webcam -- approx. FPS: 18.59 Found 2 faces and 4 eyes! (py35) $
更新1-在bash脚本中使用:
您也可以在bash脚本中使用此方法(例如,必须在特定虚拟环境中运行的脚本)。示例(添加到bash脚本中):
if [ $CONDA_DEFAULT_ENV ] ## << note the spaces (important in BASH)! then printf 'venv: operating in tf-env, proceed ...' else printf 'Note: must run this script in tf-env venv' exit fi
更新2 [2019年11月]
为简单起见,我喜欢Matt的答案(/sf/ask/17360801/)。
自从我的原始文章以来,我已经从Anaconda venv转移了(Python本身已经发展了viz -a- viz 虚拟环境)。
重新检查此问题,以下是一些更新的Python代码,您可以将其插入以测试您是否在特定的Python虚拟环境(venv)中运行。
import os, re try: if re.search('py37', os.environ['VIRTUAL_ENV']): pass except KeyError: print("\n\tPlease set the Python3 venv [alias: p3]!\n") exit()
这是一些解释性代码。
[victoria@victoria ~]$ date; python --version Thu 14 Nov 2019 11:27:02 AM PST Python 3.8.0 [victoria@victoria ~]$ python Python 3.8.0 (default, Oct 23 2019, 18:51:26) [GCC 9.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os, re >>> re.search('py37', os.environ['VIRTUAL_ENV'])>>> try: ... if re.search('py37', os.environ['VIRTUAL_ENV']): ... print('\n\tOperating in Python3 venv, please proceed! :-)') ... except KeyError: ... print("\n\tPlease set the Python3 venv [alias: p3]!\n") ... Please set the Python3 venv [alias: p3]! >>> [Ctrl-d] now exiting EditableBufferInteractiveConsole... [victoria@victoria ~]$ p3 [Python 3.7 venv (source activate py37)] (py37) [victoria@victoria ~]$ python --version Python 3.8.0 (py37) [victoria@victoria ~]$ env | grep -i virtual VIRTUAL_ENV=/home/victoria/venv/py37 (py37) [victoria@victoria ~]$ python Python 3.8.0 (default, Oct 23 2019, 18:51:26) [GCC 9.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os, re >>> try: ... if re.search('py37', os.environ['VIRTUAL_ENV']): ... print('\n\tOperating in Python3 venv, please proceed! :-)') ... except KeyError: ... print("\n\tPlease set the Python3 venv [alias: p3]!\n") ... Operating in Python3 venv, please proceed! :-) >>>
这里有多个好的答案,而有些则不太健壮。这里是概述。
怎么不做不要依赖Python或site-packages
文件夹的位置。
如果将它们设置为非标准位置,则并不意味着您实际上在虚拟环境中。用户可以安装多个Python版本,而这些版本并不总是位于您期望的位置。
避免看:
sys.executable
sys.prefix
pip -V
which python
此外,不检查的情况下venv
,.venv
或者envs
在任何这些路径。对于具有更独特位置的环境,这将不起作用。例如,
Pipenv使用哈希值作为其环境的名称。
VIRTUAL_ENV
环境变量
两者virtualenv
和venv
设置环境变量$VIRTUAL_ENV
激活一个环境时。参见PEP 405。
您可以在shell脚本中读出此变量,或使用此Python代码确定是否已设置。
import os running_in_virtualenv = "VIRTUAL_ENV" in os.environ # alternative ways to write this, also supporting the case where # the variable is set but contains an empty string to indicate # 'not in a virtual environment': running_in_virtualenv = bool(os.environ.get("VIRTUAL_ENV")) running_in_virtualenv = bool(os.getenv("VIRTUAL_ENV"))
问题是,这仅在外壳程序脚本激活了环境时才有效activate
。
您可以在不激活环境的情况下启动环境的脚本,因此,如果这是一个问题,则必须使用其他方法。
sys.real_prefix
和 sys.base_prefix
sys.prefix
如您所料,Virtualenv指向安装在virtualenv内部的Python。
同时,的原始值sys.prefix
也可以作为的新属性使用sys
:sys.real_prefix
。这就是我们用来检测我们是否在virtualenv中的方法。
import sys running_in_virtualenv = hasattr(sys, "real_prefix")
还有一个问题,但:venv
和pyvenv
来自做到这一点不同virtualenv
-他们不设置real_prefix
。而是将它们设置base_prefix
为与的不同值sys.prefix
。
为了安全起见,请按照hroncok的答案中的建议进行检查:
import sys virtualenv_prefix = getattr(sys, "real_prefix", None) venv_prefix = getattr(sys, "base_prefix", sys.prefix) running_in_virtualenv = virtualenv_prefix or venv_prefix != sys.prefix水蟒
如果您使用的是Anacona虚拟环境,请查看 Victoria Stuart的答案。