IPython von einer virtuellen Umgebung aus aufrufen

82

Ich verstehe, dass IPython nicht virtualenv-fähig ist und dass die logischste Lösung hierfür darin besteht, ipython in jedem virtualenv separat zu installieren

pip install ipython

So weit, ist es gut. Eine Sache, die mir aufgefallen ist, ist, dass, wenn die systemweite Kopie von IPython aus einer virtuellen Umgebung heraus aufgerufen wird, $> ipythonbevor IPython unter dieser virtuellen Umgebung installiert wird, nachfolgende $> ipythonBefehle weiterhin die systemweite IPython-Kopie aufrufen.

Wenn ipython jedoch vor der Installation unter einer virtuellen Umgebung nicht aufgerufen $> ipythonwird, wird die neu installierte Kopie aufgerufen .

Was ist die Erklärung dafür?

Ich frage mich auch, ob dieses Verhalten bedeutet, dass ich auf dem Weg einige Probleme erwarten sollte.

Mo Sander
quelle
10
Neuere Versionen von IPython sollten virtuelle Umgebungen erkennen, ohne dass sie separat installiert werden müssen. Beim Start wird die Meldung "Versuch, in einer virtuellen Umgebung zu arbeiten" angezeigt. Der 'sticky'-Befehl, den Sie sehen, ist das Bash-Caching des Speicherorts der ipythonausführbaren Datei irgendwo ( siehe diese Frage ).
Thomas K
Thomas, danke für den Link zum Bash-Caching, es scheint, dass genau das passiert. IPython 1.1.0 zeigt mir die Warnung "Versuch, in einer virtuellen Umgebung zu arbeiten" an, erkennt die virtuelle Umgebung jedoch nur, wenn sie in einer virtuellen Umgebung installiert ist. Aber das ist in Ordnung. Ich wollte nur sicherstellen, dass das Verfahren unproblematisch ist.
Mo Sander
7
Welche Version von virtualenv verwenden Sie und wie aktivieren Sie die Umgebung? Der fehlende Befehl hash -rlöscht den Cache zuvor ausgeführter Befehle, der normalerweise im Rahmen der Aktivierung einer Umgebung ausgeführt wird. Überprüfen Sie hash -rin ENV / bin / aktivieren.
Minrk
1
ja stimmt! Wie Thomas betonte, war dies ein Bash-Caching-Problem, das hash -rvor dem Aktivieren einer Umgebung ausgeführt wurde, um das Problem zu beheben. Zu Ihrer Information Ich habe mit virtualenv 1.10.1
Mo Sander

Antworten:

108

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

Auf diese Weise können Sie immer sicher sein, dass die ipython-Instanz immer zur Python-Version von virtualenv gehört.

Dies funktioniert nur unter ipython> 2.0.

Quelle

SiddharthaRT
quelle
1
Übrigens kann der Profilname über kwargs übergeben werden. Danke für diese Antwort!
Roboslone
20

Die Antwort von @SiddharthaRT ist gut! Nach diesem Ansatz ist es für mich einfacher:

python -m IPython

Dadurch wird das Modul IPython über den Python-Bin verwendet, um sicherzustellen, dass es auf den Bin aus der virtuellen Umgebung verweist.

jcozar87
quelle
10

Sie können IPython zwingen, eine virtuelle Umgebung zu verwenden, falls verfügbar, indem Sie die folgende Datei hinzufügen zu ~/.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)

Ich empfehle, es zu benennen, 00-virtualenv.pydamit Änderungen so früh wie möglich vorgenommen werden.

Hinweis: Stellen Sie sicher, dass ipython in der neuen virtuellen Umgebung installiert ist, damit dies funktioniert.

rgtk
quelle
1
Dies funktioniert hervorragend in Python 2-Umgebungen, aber in Envs der Version 3 erhalte ich einen ImportError, der angibt, dass es kein Modul mit dem Namen "IPython" gibt. Wenn Sie ipython3 außerhalb der Umgebung ausführen, wissen Sie, was mir hier fehlt?
efr4k
Danke dafür. Aber ich denke, die "optionale" Zeile bricht mit python3, da sys.path zu einem Filterobjekt wird, das nicht auf Listenmethoden reagiert, oder?
Motasim
5

Wie bereits erwähnt, sind neuere Versionen von ipython virtualenv-fähig. Sie können also Ihr virtualenv bin- Aktivierungsskript verwenden , um ipython mit Ihrer virtualenv auszuführen, z

$ source venv/bin/activate
(venv) $ ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
JDiMatteo
quelle
1
So viele Abstimmungen. Wenn dies für Sie nicht funktioniert, kommentieren Sie bitte mit einer Fehlermeldung und Ausgabe vonipython --version; cat /etc/issue
JDiMatteo
2
Dies funktioniert mit der IPython-Konsole, aber nicht mit anderen Dingen, zum Beispiel dem IPython-Kernel.
Błażej Michalik
5
  1. Aktivieren Sie Ihre virtuelle Umgebung mithilfe der Quelle ~ / .virtualenvs / my_venv / bin / enabled oder indem Sie workon my_venv ausführen (abhängig davon, wie Sie die virtuelle Umgebung my_venv installiert haben).

  2. Installieren Sie ipython

pip ipython installieren

  1. Führen Sie nun ipython von my_venv aus.

Wenn das Ipython des Systems weiterhin geladen wird, führen Sie es aus

Hash -r

TheDataGuy
quelle
1

Wenn Sie versuchen, ein Notebook zu öffnen, hilft auch ipython 5 nicht weiter - ipython ignoriert die virtuelle Umgebung (zumindest auf meinem Computer / Setup). Sie müssen das Skript von rgtk verwenden, aber stellen Sie sicher, dass Sie den optionalen Filterteil und die Datei sys.path.insert wie folgt ändern:

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: Im ursprünglichen Skript erhalten wir ein Filterobjekt zurück, wir würden sys.path brechen und das Einfügen unten würde fehlschlagen
  • ADD2: Siehe diese Frage und Python-Dokumentation
Fabio Scaccabarozzi
quelle
1

(Debian / Ubuntu) unter der Annahme, dass eine Version (x) von Python3 installiert ist, dann:

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

startet ipython mit Ihrer Version von Python3.

mjkrause
quelle
1

Ich werde Jahre später in der Hoffnung läuten, dass jemand dies nützlich findet.

Diese Lösung löst einige Probleme:

  • Sie müssen iPython nicht in der aktuellen virtuellen Umgebung installieren, sondern nur für die globale Python-Version, die der Python-Version ( 3.6 != 3.7) Ihrer virtuellen Umgebung entspricht .
  • Funktioniert für Benutzer, bei pyenvdenen sich Ihre globale Python-Version möglicherweise befindet 3.7und Ihre lokale virtuelle Python-Version 3.6daher die globale Version verwendet, schlägt ipythonfehl.
  • Funktioniert außerhalb virtueller Umgebungen (obwohl nicht besonders nützlich, da es immer darauf abzielt python).

Wirf das in dein ~/.bashrcoder ~/.zshrcoder was hast du:

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

Dann sourceoder öffnen Sie ein neues Terminal und führen Sie es aus ipy.

Skinner927
quelle