È possibile determinare se lo script corrente è in esecuzione all'interno di un ambiente virtualenv?
È possibile determinare se lo script corrente è in esecuzione all'interno di un ambiente virtualenv?
Risposte:
AFAIK il modo più affidabile per verificarlo (e il modo in cui viene utilizzato internamente in virtualenv e in pip) è verificare l'esistenza di sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
All'interno di un virtualenv, sys.prefix
punta alla directory virtualenv, e sys.real_prefix
indica il prefisso "reale" del sistema Python (spesso /usr
o /usr/local
o qualcosa del genere).
Al di fuori di un virtualenv, sys.real_prefix
non dovrebbe esistere.
L'uso della VIRTUAL_ENV
variabile d'ambiente non è affidabile. È impostato dallo activate
script della shell virtualenv , ma un virtualenv può essere utilizzato senza attivazione eseguendo direttamente un eseguibile dalla directory bin/
(o Scripts
) di virtualenv , nel qual caso $VIRTUAL_ENV
non verrà impostato.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Prova a usare pip -V
(nota maiuscola V)
Se stai eseguendo l'env virtuale. mostrerà il percorso verso la posizione dell'ambiente.
virtualenv
molto, è possibile che questo possa fallire o mentirti. Se sta mentendo, puoi farlo find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Se fallisce (ho "dati di marshal cattivi") dovrai cancellare i file .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(non preoccuparti, si ricostruiranno automaticamente).
...\lib\site-packages
in %PATH%
. Quindi restituirà un falso positivo in quel caso.
Questo è un miglioramento della risposta accettata da Carl Meyer . Funziona con virtualenv per Python 3 e 2 e anche per il modulo venv in Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Il controllo per le sys.real_prefix
copertine virtualenv, l'uguaglianza del non vuoto sys.base_prefix
con le sys.prefix
copertine venv.
Considera uno script che utilizza la funzione in questo modo:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
E la seguente invocazione:
$ 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
. Sto solo dicendo.
pipenv
ambienti virtuali creati.
Controlla la $VIRTUAL_ENV
variabile d'ambiente.
La $VIRTUAL_ENV
variabile di ambiente contiene la directory dell'ambiente virtuale quando si trova in un ambiente virtuale attivo.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Una volta eseguito deactivate
/ abbandonato l'ambiente virtuale, la $VIRTUAL_ENV
variabile verrà cancellata / vuota. Python genererà a KeyError
perché la variabile di ambiente non era impostata.
>>> 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'
Questi stessi controlli delle variabili d'ambiente possono ovviamente essere eseguiti anche al di fuori dello script Python, nella shell.
virtualenv
virtualenv che per venv
virtualenv.
Secondo virtualenv pep su http://www.python.org/dev/peps/pep-0405/#specification puoi semplicemente usare sys.prefix invece os.environ ['VIRTUAL_ENV'].
il sys.real_prefix non esiste nel mio virtualenv e lo stesso con il sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
che restituirà un 1 se in un venv o uno 0 in caso contrario.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
o in [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
base alle tue esigenze.
Per verificare se il tuo Virtualenv interno:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Puoi anche ottenere più dati sul tuo ambiente:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Ci sono molte buone risposte qui e alcune meno robuste. Ecco una panoramica.
Non fare affidamento sulla posizione di Python o sulla site-packages
cartella.
Se questi sono impostati su posizioni non standard, ciò non significa che in realtà ti trovi in un ambiente virtuale. Gli utenti possono avere più di una versione di Python installata e quelli non sono sempre dove ti aspetti che siano.
Evita di guardare:
sys.executable
sys.prefix
pip -V
which python
Inoltre, non verificare la presenza di venv
, .venv
o envs
in uno di questi percorsi. Ciò si interromperà per ambienti con una posizione più unica. Ad esempio,
Pipenv utilizza i valori hash come nome per i suoi ambienti.
VIRTUAL_ENV
variabile d'ambienteEntrambi virtualenv
e venv
impostare la variabile di ambiente $VIRTUAL_ENV
quando si attiva un ambiente. Vedi PEP 405 .
Puoi leggere questa variabile negli script di shell o usare questo codice Python per determinare se è impostato.
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"))
Il problema è che funziona solo quando l'ambiente è attivato dallo activate
script della shell.
Puoi avviare gli script dell'ambiente senza attivare l'ambiente , quindi se questo è un problema, devi usare un metodo diverso.
sys.base_prefix
virtualenv
, venv
E pyvenv
punto sys.prefix
al Python installata all'interno del virtualenv come ci si aspetterebbe.
Allo stesso tempo, viene reso disponibile anche il valore originale di .sys.prefix
sys.base_prefix
Possiamo usarlo per rilevare se siamo in 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
Ora attenzione, virtualenv
prima che la versione 20 non fosse impostata sys.base_prefix
ma sys.real_prefix
invece fosse impostata .
Per sicurezza, controlla entrambi come suggerito nella risposta di 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 stai utilizzando ambienti virtuali Anaconda, controlla la risposta di Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
test, che non funzionava più.
Uso abitualmente diversi ambienti virtuali (venv) installati su Anaconda. Questo frammento di codice / esempi consente di determinare se ci si trova in un venv (o nell'ambiente di sistema) e di richiedere anche un venv specifico per lo script.
Aggiungi allo script Python (frammento di codice):
# ----------------------------------------------------------------------------
# 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! ... ]
Esempio:
$ 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) $
Aggiornamento 1 - utilizzare negli script bash:
È inoltre possibile utilizzare questo approccio negli script bash (ad esempio, quelli che devono essere eseguiti in un ambiente virtuale specifico). Esempio (aggiunto allo 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
Aggiornamento 2 [nov 2019]
Dal mio post originale sono passato da Anaconda Venv (e lo stesso Python ha evoluto ambienti virtuali Viz -a-Viz ).
Riesaminando questo problema, ecco un codice Python aggiornato che è possibile inserire per verificare che si stia operando in un ambiente virtuale Python specifico (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()
Ecco qualche codice esplicativo.
[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! :-)
>>>
Il modo più semplice è semplicemente eseguire which python
:, se sei in virtualenv, punterà al suo pitone anziché a quello globale
(a cura) L'ho trovato in questo modo, cosa ne pensi? (restituisce anche il percorso di base venv e funziona anche per readthedocs dove il controllo della variabile env non lo fa):
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'] + '/../')
Ci sono già molti ottimi metodi pubblicati qui, ma aggiungo solo uno in più:
import site
site.getsitepackages()
ti dice dove sono pip
installati i pacchetti.
site.getsitepackages()
genera una directory che non è quella di sistema, puoi dedurre che ti trovi in un ambiente virtuale.
virtualenv
.
venv
stai usando.
Non è a prova di proiettile ma per ambienti UNIX test semplici come
if run("which python3").find("venv") == -1:
# something when not executed from venv
funziona benissimo per me. È più semplice quindi testare l'esistenza di alcuni attributi e, comunque, dovresti dare un nome alla tua directory venv venv
.
Nel sistema operativo Windows vedi qualcosa del genere:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Le parentesi indicano che in realtà ci si trova nell'ambiente virtuale chiamato "virtualEnvName".
Una potenziale soluzione è:
os.access(sys.executable, os.W_OK)
Nel mio caso volevo solo scoprire se potevo installare gli oggetti con pip così com'è. Anche se potrebbe non essere la soluzione giusta per tutti i casi, considera semplicemente la verifica se disponi delle autorizzazioni di scrittura per l'ubicazione dell'eseguibile Python.
Nota: funziona in tutte le versioni di Python, ma restituisce anche True
se si esegue il sistema Python con sudo
. Ecco un potenziale caso d'uso:
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'])
Questa è una vecchia domanda, ma troppi esempi sopra sono troppo complicati.
Keep It Simple: (nel terminale Jupyter Notebook o Python 3.7.1 su 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
in quel percorso, questo smetterà di funzionare quando passi da anaconda a virtualenv
o pipenv
.