virtualenvからIPythonを呼び出す


83

IPythonはvirtualenvに対応しておらず、これに対する最も論理的な解決策は、を使用して各virtualenvにipythonを個別にインストールすることであることを理解しています。

pip install ipython

ここまでは順調ですね。私が気づいたことの1つは、IPythonが$> ipythonこのvirtualenvの下にインストールされる前に、virtualenv内からIPythonのシステム全体のコピーが呼び出された場合、後続の$> ipythonコマンドがシステム全体のipythonコピーを表示し続けることです。

一方、virtualenvにインストールする前にipythonが呼び出されない場合は$> ipython、新しくインストールされたコピーが表示されます。

これの説明は何ですか?

また、この動作は、将来的に何らかの問題が発生する可能性があることを意味するのだろうかと思います。


10
IPythonの最近のバージョンでは、個別にインストールしなくてもvirtualenvを認識できるはずです。起動時に「virtualenvで作業しようとしています」というメッセージが表示されます。表示される「sticky」コマンドは、ipython実行可能ファイルの場所をどこかにbashキャッシュしています(この質問を参照)。
トーマスK

トーマス、bashキャッシングに関するリンクをありがとう、これがまさに起こっていることのようです。IPython 1.1.0は、「virtualenvで作業しようとしています」という警告を表示しますが、virtualenv内にインストールしない限り、virtualenvを認識しません。ただし、手順に問題がないことを確認したかっただけです。
Mo Sander

7
どのバージョンのvirtualenvを使用しており、どのようにenvをアクティブ化していますか?欠落しているコマンドはですhash -r。これは、以前に実行されたコマンドのキャッシュを削除します。これは通常、envのアクティブ化の一部として実行されます。hash -rENV / bin / activateで確認してください。
minrk 2013

1
そうですね!Thomasが指摘したように、これはbashキャッシュの問題でありhash -r、envをアクティブ化する前に実行すると問題が解決します。参考までに、私はvirtualenv 1.10.1で作業していました
Mo Sander

回答:


108

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

これは、ipythonインスタンスが常にvirtualenvのpythonバージョンに属していることを常に確認するための優れた方法です。

これは、ipython> 2.0でのみ機能します。

ソース


1
ところで、プロファイル名はkwargsを介して渡すことができます。その答えをありがとう!
roboslone 2015年

22

@SiddharthaRTによって与えられた答えは良いです!このアプローチに従うと、私にとっては簡単です。

python -m IPython

これは、Python binを介してモジュールIPythonを使用し、仮想環境からのbinを参照するようにします。


10

以下のファイルを追加することで、可能な場合はIPythonに仮想環境の使用を強制できます~/.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)

00-virtualenv.pyできるだけ早く変更が加えられるように、名前を付けることをお勧めします。

注:これを機能させるには、ipythonが新しい仮想環境にインストールされていることを確認してください。


1
これはPython2環境ではうまく機能しますが、バージョン3環境では、「IPython」という名前のモジュールがないことを示すImportErrorが発生します。環境外でipython3を実行すると機能しますが、ここで何が欠けているか知っていますか?
efr4k 2016

これをありがとう。しかし、sys.pathがリストメソッドに応答しないフィルターオブジェクトになるため、「オプション」の行はpython3で壊れると思います。
モタ

5

他の人が述べたように、ipythonの最近のバージョンはvirtualenvに対応しているため、virtualenv bin activateスクリプトを使用して、virtualenvを使用してipythonを実行できます。

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

1
非常に多くの反対票。これがうまくいかない場合は、エラーメッセージと出力をコメントしてくださいipython --version; cat /etc/issue
JDiMatteo 2017年

2
これはIPythonのコンソールでは機能しますが、IPythonカーネルなどの他のものでは機能しません。
BłażejMichalik

5
  1. ソース〜/ .virtualenvs / my_venv / bin / activateを使用するか、workon my_venvを実行して仮想環境をアクティブ化します (my_venv仮想環境のインストール方法によって異なります)

  2. ipythonをインストールします

pip install ipython

  1. 次に、my_venvからipythonを実行します。

それでもシステムのipythonが読み込まれる場合は、実行します

ハッシュ-r


1

ノートブックを開こうとしている場合、ipython 5でも役に立ちません-ipythonはvirtualenvを無視します(少なくとも私のマシン/セットアップでは)。rgtkのスクリプトを使用する必要がありますが、オプションのフィルター部分とsys.path.insertを以下のように変更してください。

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:元のスクリプトでフィルターオブジェクトを取得すると、sys.pathが壊れ、以下の挿入が失敗します
  • ADD2:この質問Pythonのドキュメントを参照してください

1

(Debian / Ubuntu)Python3のバージョン(x)がインストールされていると仮定すると、次のようになります。

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

お使いのバージョンのPython3を実行するipythonを起動します。


1

誰かがこれが役に立つと思うことを願って、私は数年後にチャイムを鳴らします。

このソリューションは、いくつかの問題を解決します。

  • 現在のvirtualenvにiPythonをインストールする必要はありません。virtualenvのPythonバージョンと一致するグローバルPythonの場合のみです(3.6 != 3.7)。
  • pyenvグローバルPythonバージョンが存在する可能性が3.7ある3.6ため、ローカルvirtualenvPythonがグローバルを使用しているユーザー向けに機能しますipythonは機能しません。
  • 仮想環境の外部で機能します(ただし、常に対象となるため、特に有用ではありませんpython)。

これをあなたの~/.bashrcまたは~/.zshrcまたはあなたが持っているものに投げてください:

# 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
}

次に、sourceまたは新しいターミナルを開いてを実行しipyます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.