是否可以确定当前脚本是否在virtualenv环境中运行?
是否可以确定当前脚本是否在virtualenv环境中运行?
Answers:
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
将不会设置。
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
尝试使用pip -V
(注意大写V)
如果您正在运行虚拟环境。它会显示到环境位置的路径。
virtualenv
四处走动,则可能会失败或对您说谎。如果它在说谎,你可以做find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
。如果失败(我收到“不良元帅数据”),则需要擦除.pyc文件find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(不用担心,它们会自动重建)。
...\lib\site-packages
中打印出pip的位置%PATH%
。因此,在这种情况下,它将返回误报。
这是对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
def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
。只是在说'。
pipenv
创建的虚拟环境。
检查$VIRTUAL_ENV
环境变量。
$VIRTUAL_ENV
在活动的虚拟环境中,环境变量包含虚拟环境的目录。
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
一旦运行deactivate
/离开虚拟环境,该$VIRTUAL_ENV
变量将被清除/为空。Python将引发一个,KeyError
因为未设置环境变量。
>>> import os
>>> os.environ['VIRTUAL_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
raise KeyError(key) from None
KeyError: 'VIRTUAL_ENV'
当然,这些相同的环境变量检查也可以在外壳程序中的Python脚本之外进行。
virtualenv
virtualenv和venv
virtualenv均有效。
根据http://www.python.org/dev/peps/pep-0405/#specification上的virtualenv pep,您可以只使用sys.prefix代替os.environ ['VIRTUAL_ENV']。
sys.real_prefix在我的virtualenv中不存在,与sys.base_prefix相同。
sys.real_prefix
。
env |grep VIRTUAL_ENV |wc -l
如果在venv中返回1,否则返回0。
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
或使用[[ -z $VIRTUAL_ENV ]] && echo not virtualenv
。
要检查您的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")}')
这里有多个好的答案,而有些则不太健壮。这里是概述。
不要依赖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"))
问题是,这仅在环境由Shell脚本激活时有效activate
。
您可以在不激活环境的情况下启动环境的脚本,因此,如果这是一个问题,则必须使用其他方法。
sys.base_prefix
virtualenv
,venv
然后按预期pyvenv
指向sys.prefix
安装在virtualenv内部的Python。
同时,的原始值sys.prefix
也可作为获得sys.base_prefix
。
我们可以使用它来检测我们是否在virtualenv中。
import sys
# note: Python versions before 3.3 don't have sys.base_prefix
# if you're not in virtual environment
running_in_virtualenv = sys.prefix != sys.base_prefix
sys.real_prefix
现在请注意,virtualenv
在未设置版本20之前,而是设置了sys.base_prefix
它sys.real_prefix
。
为了安全起见,请按照hroncok的答案中的建议进行检查:
import sys
real_prefix = getattr(sys, "real_prefix", None)
base_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv = (base_prefix or real_prefix) != sys.prefix
如果您使用的是Anaconda虚拟环境,请查看 Victoria Stuart的答案。
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
测试,该测试不再有效。
我通常使用几个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月]
自从我的原始文章以来,我已经从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'])
<re.Match object; span=(20, 24), match='py37'>
>>> 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! :-)
>>>
最简单的方法是运行:which python
,如果您位于virtualenv中,它将指向其python而不是全局的python
(编辑)我发现那条路,您怎么看?(它还会返回venv基本路径,甚至可以在不检查env变量的readthedocs中使用):
import os
import sys
from distutils.sysconfig import get_config_vars
def get_venv_basedir():
"""Returns the base directory of the virtualenv, useful to read configuration and plugins"""
exec_prefix = get_config_vars()['exec_prefix']
if hasattr(sys, 'real_prefix') is False or exec_prefix.startswith(sys.real_prefix):
raise EnvironmentError('You must be in a virtual environment')
return os.path.abspath(get_config_vars()['exec_prefix'] + '/../')
已经在这里发布了很多很棒的方法,但是只添加了一个:
import site
site.getsitepackages()
告诉您pip
软件包的安装位置。
site.getsitepackages()
输出的目录不是系统目录,则可以推断出您处于虚拟环境中。
virtualenv
。
venv
。
一个可能的解决方案是:
os.access(sys.executable, os.W_OK)
就我而言,我真的只是想检测是否可以按原样安装pip物品。尽管这可能不是适用于所有情况的正确解决方案,但请考虑简单地检查一下是否对Python可执行文件的位置具有写权限。
注意:这适用于所有版本的Python,但True
如果您使用来运行系统Python,也将返回sudo
。这是一个潜在的用例:
import os, sys
can_install_pip_packages = os.access(sys.executable, os.W_OK)
if can_install_pip_packages:
import pip
pip.main(['install', 'mypackage'])
这是一个古老的问题,但是上面的例子太多了。
保持简单:(在Windows 10的Jupyter Notebook或Python 3.7.1终端中)
import sys
print(sys.executable)```
# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`
OR
```sys.base_prefix```
# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
envs
该路径中是否存在,当您从anaconda移至virtualenv
或时,这将停止工作pipenv
。