É possível determinar se o script atual está sendo executado dentro de um ambiente virtualenv?
É possível determinar se o script atual está sendo executado dentro de um ambiente virtualenv?
Respostas:
AFAIK, a maneira mais confiável de verificar isso (e a maneira usada internamente no virtualenv e no pip) é verificar a existência de sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Dentro de um virtualenv, sys.prefix
aponta para o diretório virtualenv, e sys.real_prefix
aponta para o prefixo "real" do sistema Python (muitas vezes /usr
ou /usr/local
ou algo assim).
Fora de um virtualenv, sys.real_prefix
não deveria existir.
O uso da VIRTUAL_ENV
variável de ambiente não é confiável. Ele é definido pelo activate
script de shell virtualenv , mas um virtualenv pode ser usado sem ativação, executando diretamente um executável do diretório virtualenv bin/
(ou Scripts
), caso em que $VIRTUAL_ENV
não será definido.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Tente usar pip -V
(aviso capital V)
Se você estiver executando o ambiente virtual. mostrará o caminho para a localização do ambiente.
virtualenv
muito sua situação, é possível que isso possa falhar ou mentir para você. Se está mentindo, você pode fazer find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Se estiver falhando (recebi "dados de marechal incorretos"), você precisará limpar os arquivos .pyc com find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(não se preocupe, eles serão reconstruídos automaticamente).
...\lib\site-packages
no %PATH%
. Portanto, ele retornará um falso positivo nesse caso.
Esta é uma melhoria da resposta aceita por Carl Meyer . Ele funciona com virtualenv para Python 3 e 2 e também para o módulo venv no Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
A verificação de sys.real_prefix
covers virtualenv, a igualdade de não-vazio sys.base_prefix
com sys.prefix
covers venv.
Considere um script que usa a função assim:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
E a seguinte invocação:
$ 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
. Apenas dizendo'.
pipenv
ambientes virtuais criados.
Verifique a $VIRTUAL_ENV
variável de ambiente.
A $VIRTUAL_ENV
variável de ambiente contém o diretório do ambiente virtual quando em um ambiente virtual ativo.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Depois de executar deactivate
/ sair do ambiente virtual, a $VIRTUAL_ENV
variável será limpa / vazia. Python irá gerar um KeyError
porque a variável de ambiente não está definida.
>>> 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'
Naturalmente, essas mesmas verificações de variáveis de ambiente também podem ser feitas fora do script Python, no shell.
virtualenv
virtualenv e um venv
virtualenv.
De acordo com o virtualenv pep em http://www.python.org/dev/peps/pep-0405/#specification, você pode usar o sys.prefix em vez do os.environ ['VIRTUAL_ENV'].
o sys.real_prefix não existe no meu virtualenv e o mesmo no sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
que retornará 1 se estiver em um venv ou 0 se não estiver.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
ou [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
dependendo de suas necessidades.
Para verificar se o seu Virtualenv interno:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Você também pode obter mais dados sobre o seu ambiente:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Existem várias boas respostas aqui e outras menos robustas. Aqui está uma visão geral.
Não confie na localização do Python ou na site-packages
pasta.
Se eles estiverem configurados para locais fora do padrão, isso não significa que você esteja realmente em um ambiente virtual. Os usuários podem ter mais de uma versão do Python instalada, e essas nem sempre são as que você espera.
Evite olhar para:
sys.executable
sys.prefix
pip -V
which python
Além disso, não verificar a presença de venv
, .venv
ou envs
em qualquer um desses caminhos. Isso ocorrerá em ambientes com um local mais exclusivo. Por exemplo, o
Pipenv usa valores de hash como o nome para seus ambientes.
VIRTUAL_ENV
variável de ambienteAmbos virtualenv
e venv
defina a variável de ambiente $VIRTUAL_ENV
ao ativar um ambiente. Veja PEP 405 .
Você pode ler essa variável em scripts de shell ou usar esse código Python para determinar se está definido.
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"))
O problema é que isso só funciona quando o ambiente é ativado pelo activate
script de shell.
Você pode iniciar os scripts do ambiente sem ativar o ambiente ; portanto, se isso for uma preocupação, você precisará usar um método diferente.
sys.base_prefix
virtualenv
, venv
E pyvenv
ponto sys.prefix
para o Python instalado dentro do virtualenv como seria de esperar.
Ao mesmo tempo, o valor original de sys.prefix
também é disponibilizado como sys.base_prefix
.
Podemos usar isso para detectar se estamos em um 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
Agora, tenha cuidado, virtualenv
antes da versão 20 não ter sido definida, sys.base_prefix
mas sys.real_prefix
sim.
Para estar seguro, marque os dois conforme sugerido na resposta da 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
Se você estiver usando ambientes virtuais do Anaconda, verifique a resposta de Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
teste, que não funcionava mais.
Você pode fazer which python
e ver se está apontando para o ambiente virtual.
which
não está disponível por padrão no Windows. Em where
vez disso, você pode usar no Windows ou empregar artesanato . Ou olhe sys.executable
. Mas, ainda assim, existem métodos melhores.
Uso rotineiramente vários ambientes virtuais instalados pelo Anaconda (venv). Este trecho de código / exemplos permite determinar se você está ou não em um venv (ou no ambiente do sistema) e também exige um venv específico para o seu script.
Adicione ao script Python (trecho de código):
# ----------------------------------------------------------------------------
# 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! ... ]
Exemplo:
$ 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) $
Atualização 1 - use em scripts bash:
Você também pode usar essa abordagem em scripts bash (por exemplo, aqueles que devem ser executados em um ambiente virtual específico). Exemplo (adicionado ao script 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
Atualização 2 [novembro de 2019]
Desde o meu post original, mudei de Anaconda venv (e o próprio Python evoluiu ambientes virtuais viz-a-viz ).
Reexaminando esse problema, eis alguns códigos Python atualizados que você pode inserir para testar se está operando em um ambiente virtual Python específico (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()
Aqui está um código explicativo.
[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! :-)
>>>
A maneira mais fácil é simplesmente executar which python
:, se você estiver em um virtualenv, ele apontará para o python em vez do global
(editada) Encontrei assim, o que você acha disso? (ele também retorna o caminho base venv e funciona mesmo para readthedocs onde a verificação da variável env não):
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'] + '/../')
Já existem muitos ótimos métodos publicados aqui, mas apenas adicionamos mais um:
import site
site.getsitepackages()
informa onde pip
os pacotes foram instalados.
site.getsitepackages()
gerar um diretório que não seja o sistema, você poderá deduzir que está em um ambiente virtual.
virtualenv
.
venv
você está usando.
Não é à prova de balas, mas para ambientes UNIX, teste simples como
if run("which python3").find("venv") == -1:
# something when not executed from venv
funciona muito bem para mim. É mais simples do que testar os atributos existentes e, de qualquer forma, você deve nomear seu diretório venv venv
.
No sistema operacional Windows, você vê algo assim:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Parênteses significam que você está realmente no ambiente virtual chamado "virtualEnvName".
Uma solução potencial é:
os.access(sys.executable, os.W_OK)
No meu caso, eu realmente só queria detectar se poderia instalar itens com o pip como está. Embora possa não ser a solução certa para todos os casos, considere simplesmente verificar se você possui permissões de gravação para o local do executável do Python.
Nota: isso funciona em todas as versões do Python, mas também retorna True
se você executar o sistema com o Python sudo
. Aqui está um caso de uso potencial:
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'])
Esta é uma pergunta antiga, mas muitos exemplos acima são muito complicados.
Mantenha as coisas simples: (no terminal Jupyter Notebook ou Python 3.7.1 no Windows 10)
import sys
print(sys.executable)```
# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`
OR
```sys.base_prefix```
# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
envs
desse caminho, isso parará de funcionar quando você passar do anaconda para virtualenv
ou pipenv
.