Gọi IPython từ virtualenv


83

Tôi hiểu rằng IPython không nhận biết được virtualenv và giải pháp hợp lý nhất cho việc này là cài đặt ipython trong từng virtualenv riêng biệt bằng cách sử dụng

pip install ipython

Càng xa càng tốt. Một điều tôi nhận thấy là nếu bản sao toàn hệ thống của IPython được gọi từ bên trong virtualenv bằng cách sử dụng $> ipythontrước khi IPython được cài đặt dưới virtualenv này, các $> ipythonlệnh tiếp theo sẽ tiếp tục hiển thị bản sao ipython trên toàn hệ thống.

Mặt khác, nếu ipython không được gọi trước khi cài đặt nó dưới virtualenv $> ipythonsẽ hiển thị bản sao mới được cài đặt.

Lời giải thích cho điều này là gì?

Nó cũng khiến tôi tự hỏi liệu hành vi này có nghĩa là tôi có nên mong đợi một số rắc rối trong tương lai không?


10
Các phiên bản gần đây của IPython sẽ nhận dạng virtualenv mà không cần cài đặt riêng - bạn sẽ thấy thông báo "đang cố gắng hoạt động trong virtualenv" khi nó khởi động. Lệnh 'dính' mà bạn thấy đang lưu vào bộ nhớ đệm vị trí của ipythontệp thực thi ở đâu đó ( xem câu hỏi này ).
Thomas K

Thomas, cảm ơn vì liên kết về bộ nhớ đệm bash, có vẻ như đây chính xác là những gì sẽ xảy ra. IPython 1.1.0 hiển thị cho tôi cảnh báo 'Đang cố gắng làm việc trong virtualenv' nhưng nó không nhận ra virtualenv trừ khi được cài đặt trong virtualenv - nhưng điều đó tốt, tôi chỉ muốn đảm bảo quy trình này không có vấn đề.
Mo Sander

7
bạn đang sử dụng phiên bản virtualenv nào và bạn kích hoạt env như thế nào? Lệnh bạn đang thiếu là lệnh hash -rxóa bộ nhớ cache của các lệnh đã chạy trước đó, lệnh này thường được thực thi như một phần của việc kích hoạt một env. Kiểm tra hash -rENV / bin / kích hoạt.
minrk.

1
Vâng đúng! Như Thomas đã chỉ ra, đây là một vấn đề bộ nhớ đệm bash và việc chạy hash -rtrước khi kích hoạt một env sẽ giải quyết được vấn đề. FYI Tôi đang làm việc với virtualenv 1.10.1
Mo Sander.

Câu trả lời:


108

alias ipy="python -c 'import IPython; IPython.terminal.ipapp.launch_new_instance()'"

Đây là một cách tuyệt vời để luôn đảm bảo rằng phiên bản ipython luôn thuộc về phiên bản python của virtualenv.

Điều này chỉ hoạt động trên ipython> 2.0.

Nguồn


1
BTW, tên hồ sơ có thể được thông qua kwargs. Cảm ơn vì câu trả lời đó!
roboslone

22

Câu trả lời được đưa ra bởi @SiddharthaRT là tốt! Theo cách tiếp cận này, đối với tôi đơn giản hơn chỉ:

python -m IPython

Thao tác này sẽ sử dụng IPython của mô-đun thông qua bin python, đảm bảo rằng nó tham chiếu đến bin từ env ảo.


10

Bạn có thể buộc IPython sử dụng môi trường ảo nếu có bằng cách thêm tệp bên dưới vào ~/.ipython/profile_default/startups:

import os
import sys

if 'VIRTUAL_ENV' in os.environ:
    py_version = sys.version_info[:2] # formatted as X.Y 
    py_infix = os.path.join('lib', ('python%d.%d' % py_version))
    virtual_site = os.path.join(os.environ.get('VIRTUAL_ENV'), py_infix, 'site-packages')
    dist_site = os.path.join('/usr', py_infix, 'dist-packages')

    # OPTIONAL: exclude debian-based system distributions sites
    sys.path = filter(lambda p: not p.startswith(dist_site), sys.path)

    # add virtualenv site
    sys.path.insert(0, virtual_site)

Tôi khuyên bạn nên đặt tên cho nó 00-virtualenv.pyđể các thay đổi sẽ được thực hiện sớm nhất có thể.

Lưu ý: Đảm bảo rằng ipython đã được cài đặt trong môi trường ảo mới để làm cho điều này hoạt động.


1
Điều này hoạt động tốt trong môi trường Python 2, nhưng trong phiên bản 3 envs, tôi nhận được lỗi ImportError cho biết không có mô-đun nào có tên "IPython". Chạy ipython3 ngoài môi trường hoạt động, bạn có biết ở đây tôi còn thiếu điều gì không?
efr4k

Cám ơn vì cái này. Nhưng tôi nghĩ rằng dòng "Tùy chọn" ngắt với python3 vì sys.path trở thành một đối tượng bộ lọc không phản hồi với các phương thức danh sách, phải không?
mota

5

Như những người khác đã đề cập, các phiên bản gần đây của ipython có nhận dạng virtualenv, vì vậy bạn có thể sử dụng tập lệnh kích hoạt virtualenv bin để chạy ipython bằng virtualenv của bạn, ví dụ:

$ source venv/bin/activate
(venv) $ ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.

1
Rất nhiều phiếu phản đối. Nếu điều này không làm việc cho bạn, xin vui lòng bình luận với một thông báo lỗi và đầu ra củaipython --version; cat /etc/issue
JDiMatteo

2
Điều này sẽ hoạt động với giao diện điều khiển của IPython, nhưng sẽ không hoạt động với những thứ khác, ví dụ hạt nhân IPython.
Błażej Michalik

5
  1. Kích hoạt môi trường ảo của bạn bằng cách sử dụng source ~ / .virtualenvs / my_venv / bin / active hoặc bằng cách chạy workon my_venv (Tùy thuộc vào cách bạn đã cài đặt môi trường ảo my_venv)

  2. Cài đặt ipython

pip cài đặt ipython

  1. Bây giờ chạy ipython từ my_venv.

Nếu nó vẫn tải ipython của hệ thống, thì hãy chạy

băm -r


1

Nếu bạn đang cố gắng mở sổ ghi chép, ngay cả ipython 5 cũng không giúp được gì - ipython sẽ bỏ qua virtualenv (ít nhất là trên máy / thiết lập của tôi). Bạn sẽ cần sử dụng tập lệnh của rgtk, nhưng hãy đảm bảo sửa đổi phần bộ lọc tùy chọn và sys.path.insert như bên dưới:

import os
import sys

if 'VIRTUAL_ENV' in os.environ:
    py_version = sys.version_info[:2] # formatted as X.Y 
    py_infix = os.path.join('lib', ('python%d.%d' % py_version))
    virtual_site = os.path.join(os.environ.get('VIRTUAL_ENV'), py_infix, 'site-packages')
    dist_site = os.path.join('/usr', py_infix, 'dist-packages')

    # OPTIONAL: exclude debian-based system distributions sites
    # ADD1: sys.path must be a list
    sys.path = list(filter(lambda p: not p.startswith(dist_site), sys.path))

    # add virtualenv site
    # ADD2: insert(0 is wrong and breaks conformance of sys.path
    sys.path.insert(1, virtual_site)
  • ADD1: trong script gốc, chúng tôi lấy lại một đối tượng bộ lọc, chúng tôi sẽ phá vỡ sys.path và chèn bên dưới sẽ không thành công
  • ADD2: xem câu hỏi nàytài liệu về python

1

(Debian / Ubuntu) giả sử một số phiên bản (x) của Python3 được cài đặt, thì:

$ sudo apt-get install -y ipython
$ virtualenv --python=python3.x .venv
$ source .venv/bin/activate
$ pip3 install ipython
$ ipython3

sẽ khởi chạy ipython chạy phiên bản Python3 của bạn.


1

Tôi sẽ kêu gọi trong nhiều năm sau với hy vọng ai đó thấy điều này hữu ích.

Giải pháp này giải quyết một số vấn đề:

  • Bạn không cần cài đặt iPython trong virtualenv hiện tại, chỉ dành cho Python toàn cầu khớp với phiên bản Python của virtualenv ( 3.6 != 3.7).
  • Hoạt động cho người dùng ở pyenvnơi có thể có phiên bản Python toàn cầu của bạn 3.73.6do đó, Python virtualenv cục bộ của bạn đang sử dụng toàn cầu ipythonsẽ không thành công.
  • Hoạt động bên ngoài môi trường ảo (mặc dù không đặc biệt hữu ích vì nó luôn nhắm mục tiêu python).

Hãy ném cái này vào của bạn ~/.bashrchoặc của ~/.zshrcbạn:

# This is a roundabout way to start ipython from inside a virtualenv without it being installed
# in that virtualenv. The only caveot is that the "global" python must have ipython installed.
# What this function does that's different than simply calling the global ipython is it ensures to
# call the ipython that is installed for the same major.minor python version as in the virtualenv.
# This is most useful if you use pyenv for example as global python3 could be 3.7 and local
# virtualenv python3 is 3.6.
function ipy {
  local PY_BIN
  local IPYTHON
  local PYV
  # This quick way will work if ipython is in the virtualenv
  PY_BIN="$(python -c 'import sys; print(sys.executable)')"
  IPYTHON="$(dirname "$PY_BIN")/ipython"
  if [[ -x "$IPYTHON" ]]; then
    "$IPYTHON"
  else
    # Ask the current python what version it is
    PYV="$(python -c 'import sys; print(".".join(str(i) for i in sys.version_info[:2]))')"
    echo "Looking for iPython for Python $PYV"
    # In a new shell (where pyenv should load if equipped) try to find that version
    PY_BIN="$($SHELL -i -c "python$PYV -c 'import sys; print(sys.executable)'")"
    "$(dirname "$PY_BIN")/ipython"
  fi
}

Sau đó sourcehoặc mở một thiết bị đầu cuối mới và chạy ipy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.