Có thể xác định xem tập lệnh hiện tại có chạy trong môi trường virtualenv không?
Có thể xác định xem tập lệnh hiện tại có chạy trong môi trường virtualenv không?
Câu trả lời:
AFAIK cách đáng tin cậy nhất để kiểm tra điều này (và cách được sử dụng nội bộ trong virtualenv và trong pip) là kiểm tra sự tồn tại của sys.real_prefix
:
import sys
if hasattr(sys, 'real_prefix'):
#...
Bên trong một virtualenv, sys.prefix
điểm đến thư mục virtualenv, và sys.real_prefix
điểm đến tiếp đầu ngữ "thực" của hệ thống Python (thường /usr
hay /usr/local
hoặc một số như vậy).
Bên ngoài một virtualenv, sys.real_prefix
không nên tồn tại.
Sử dụng VIRTUAL_ENV
biến môi trường là không đáng tin cậy. Nó được thiết lập bởi activate
tập lệnh shell virtualenv , nhưng virtualenv có thể được sử dụng mà không cần kích hoạt bằng cách chạy trực tiếp một tệp thực thi từ thư mục bin/
(hoặc Scripts
) của virtualenv , trong trường hợp $VIRTUAL_ENV
này sẽ không được đặt.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Hãy thử sử dụng pip -V
(thông báo vốn V)
Nếu bạn đang chạy env ảo. nó sẽ hiển thị đường dẫn đến vị trí của env.
virtualenv
xung quanh rất nhiều, điều đó có thể thất bại hoặc nói dối bạn. Nếu đó là nói dối, bạn có thể làm find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+
. Nếu nó không thành công (tôi có "dữ liệu thống kê xấu"), bạn sẽ cần xóa các tệp .pyc bằng find /path/to/venv -type f -name "*.pyc" -exec rm {} \+
(đừng lo lắng, chúng sẽ tự động xây dựng lại).
...\lib\site-packages
trong %PATH%
. Vì vậy, nó sẽ trả lại một dương tính giả trong trường hợp đó.
Đây là một cải tiến của câu trả lời được chấp nhận bởi Carl Meyer . Nó hoạt động với virtualenv cho Python 3 và 2 và cả cho mô-đun venv trong Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
Việc kiểm tra sys.real_prefix
bao gồm virtualenv, sự bình đẳng của không trống sys.base_prefix
với sys.prefix
bìa venv.
Hãy xem xét một tập lệnh sử dụng chức năng như thế này:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
Và lời mời sau:
$ 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
. Chỉ cần nói.
pipenv
môi trường ảo được tạo.
Kiểm tra $VIRTUAL_ENV
biến môi trường.
Biến $VIRTUAL_ENV
môi trường chứa thư mục của môi trường ảo khi ở trong môi trường ảo hoạt động.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Khi bạn chạy deactivate
/ rời khỏi môi trường ảo, $VIRTUAL_ENV
biến sẽ bị xóa / trống. Python sẽ tăng a KeyError
vì biến môi trường không được đặt.
>>> 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'
Các kiểm tra biến môi trường tương tự này tất nhiên cũng có thể được thực hiện bên ngoài tập lệnh Python, trong trình bao.
virtualenv
virtualenv và venv
virtualenv.
Theo virtualenv pep tại http://www.python.org/dev/peps/pep-0405/#specification bạn chỉ có thể sử dụng sys.prefix thay vì os.envir ['VIRTUAL_ENV'].
sys.real_prefix không tồn tại trong virtualenv của tôi và tương tự với sys.base_prefix.
sys.real_prefix
.
env |grep VIRTUAL_ENV |wc -l
nó sẽ trả về 1 nếu trong venv hoặc 0 nếu không.
[[ -n $VIRTUAL_ENV ]] && echo virtualenv
hoặc [[ -z $VIRTUAL_ENV ]] && echo not virtualenv
tùy theo nhu cầu của bạn.
Để kiểm tra xem Virtualenv bên trong của bạn:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
Bạn cũng có thể nhận được nhiều dữ liệu hơn về môi trường của mình:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Bạn có thể làm which python
và xem nếu nó trỏ đến một trong env ảo.
which
không có sẵn theo mặc định trên Windows. Bạn có thể sử dụng where
thay thế trên Windows hoặc sử dụng whichcraft . Hoặc nhìn vào sys.executable
. Nhưng vẫn có những phương pháp tốt hơn.
Có nhiều câu trả lời tốt ở đây, và một số câu trả lời ít mạnh mẽ hơn. Đây là một cái nhìn tổng quan.
Không dựa vào vị trí của Python hoặc site-packages
thư mục.
Nếu các vị trí này được đặt thành các vị trí không chuẩn, điều đó không có nghĩa là bạn thực sự ở trong một môi trường ảo. Người dùng có thể cài đặt nhiều hơn một phiên bản Python và những phiên bản đó không phải lúc nào cũng như bạn mong đợi.
Tránh nhìn vào:
sys.executable
sys.prefix
pip -V
which python
Ngoài ra, không kiểm tra sự hiện diện của venv
, .venv
hoặc envs
trong bất kỳ đường dẫn nào trong số này. Điều này sẽ phá vỡ cho các môi trường với một vị trí độc đáo hơn. Ví dụ,
Pipenv sử dụng các giá trị băm làm tên cho các môi trường của nó.
VIRTUAL_ENV
biến môi trườngCả hai virtualenv
và venv
đặt biến môi trường $VIRTUAL_ENV
khi kích hoạt một môi trường. Xem PEP 405 .
Bạn có thể đọc biến này trong các tập lệnh shell hoặc sử dụng mã Python này để xác định xem nó có được đặt không.
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"))
Vấn đề là, điều này chỉ hoạt động khi môi trường được kích hoạt bởi activate
tập lệnh shell.
Bạn có thể bắt đầu các tập lệnh của môi trường mà không kích hoạt môi trường , vì vậy nếu đó là vấn đề đáng lo ngại, bạn phải sử dụng một phương pháp khác.
sys.base_prefix
virtualenv
, venv
Và pyvenv
điểm sys.prefix
đến Python được cài đặt bên trong virtualenv như bạn mong đợi.
Đồng thời, giá trị ban đầu của sys.prefix
cũng được cung cấp dưới dạng sys.base_prefix
.
Chúng ta có thể sử dụng điều đó để phát hiện nếu chúng ta đang ở trong một 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
Bây giờ hãy coi chừng, virtualenv
trước khi phiên bản 20 không được thiết lập sys.base_prefix
mà sys.real_prefix
thay vào đó nó được đặt .
Vì vậy, để an toàn, hãy kiểm tra cả hai như được đề xuất trong câu trả lời của 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
Nếu bạn đang sử dụng môi trường ảo Anaconda, hãy kiểm tra câu trả lời của Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):
bài kiểm tra, mà không còn làm việc nữa.
Tôi thường xuyên sử dụng một số môi trường ảo được cài đặt Anaconda (venv). Đoạn mã / ví dụ này cho phép bạn xác định xem bạn có đang ở trong một venv (hoặc môi trường hệ thống của bạn) hay không và cũng yêu cầu một venv cụ thể cho tập lệnh của bạn.
Thêm vào tập lệnh Python (đoạn mã):
# ----------------------------------------------------------------------------
# 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! ... ]
Thí dụ:
$ 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) $
Cập nhật 1 - sử dụng trong tập lệnh bash:
Bạn cũng có thể sử dụng phương pháp này trong các tập lệnh bash (ví dụ: các tập lệnh phải chạy trong một môi trường ảo cụ thể). Ví dụ (được thêm vào tập lệnh 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
Cập nhật 2 [tháng 11 năm 2019]
Vì bài viết gốc của tôi, tôi đã chuyển từ Anaconda venv (và chính Python đã phát triển môi trường ảo viz-a-viz ).
Xem xét lại vấn đề này, đây là một số mã Python được cập nhật mà bạn có thể chèn để kiểm tra xem bạn có đang hoạt động trong một môi trường ảo Python cụ thể (venv) không.
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()
Đây là một số mã giải thích.
[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! :-)
>>>
Cách dễ nhất là chỉ chạy : which python
, nếu bạn đang ở trong một virtualenv, nó sẽ trỏ đến con trăn của nó thay vì toàn cầu
(chỉnh sửa) Tôi tìm thấy theo cách đó, bạn nghĩ gì về nó? (nó cũng trả về đường dẫn cơ sở venv và hoạt động ngay cả đối với readthedocs nơi kiểm tra biến env không):
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'] + '/../')
Có rất nhiều phương pháp tuyệt vời được đăng ở đây, nhưng chỉ cần thêm một phương pháp nữa:
import site
site.getsitepackages()
cho bạn biết nơi pip
cài đặt các gói.
site.getsitepackages()
xuất ra một thư mục không phải là hệ thống, thì bạn có thể suy luận bạn đang ở trong một môi trường ảo.
virtualenv
.
venv
bạn đang sử dụng.
Nó không chống đạn nhưng đối với môi trường UNIX, thử nghiệm đơn giản như
if run("which python3").find("venv") == -1:
# something when not executed from venv
làm việc tuyệt vời cho tôi Sau đó, đơn giản hơn là kiểm tra một số thuộc tính và dù sao, bạn nên đặt tên cho thư mục venv của mình venv
.
Trong hệ điều hành windows, bạn sẽ thấy một cái gì đó như thế này:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Dấu ngoặc có nghĩa là bạn thực sự đang ở trong môi trường ảo được gọi là "virtualEnvName".
Một giải pháp tiềm năng là:
os.access(sys.executable, os.W_OK)
Trong trường hợp của tôi, tôi thực sự chỉ muốn phát hiện nếu tôi có thể cài đặt các mục với pip. Mặc dù nó có thể không phải là giải pháp phù hợp cho mọi trường hợp, hãy xem xét đơn giản là kiểm tra xem bạn có quyền ghi đối với vị trí của tệp thực thi Python hay không.
Lưu ý: điều này hoạt động trong tất cả các phiên bản của Python, nhưng cũng trả về True
nếu bạn chạy hệ thống Python với sudo
. Đây là trường hợp sử dụng tiềm năng:
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'])
Đây là một câu hỏi cũ, nhưng quá nhiều ví dụ ở trên quá phức tạp.
Giữ cho nó đơn giản: (trong Jupyter Notebook hoặc thiết bị đầu cuối Python 3.7.1 trên 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
đường dẫn đó, điều này sẽ ngừng hoạt động khi bạn chuyển từ anaconda sang virtualenv
hoặc pipenv
.