Python-Modul im Code installieren

310

Ich muss ein Paket von PyPi direkt in meinem Skript installieren. Vielleicht gibt es einige Modul oder distutils( distribute, pipetc.) Funktion , die mir erlaubt , nur so etwas wie ausführen pypi.install('requests')und Anfragen werden in meine virtualenv installiert werden.

chuwy
quelle
4
Warum definieren Sie das zugehörige Modul nicht als Abhängigkeit in der setup.py Ihres eigenen Pakets?
Andreas Jung
5
Sie wissen ... wie es eigentlich gemacht werden soll ... aber Sie könnten immer os.system ("pip install blah"), aber Sie benötigen möglicherweise einen Sudo-Zugriff ... besser, um es einfach zu einer Abhängigkeit in Ihrem Setup zu machen. py
Joran Beasley
2
Würden Sie erwägen, die akzeptierte Antwort hier zu ändern? Importieren pipist nie eine gute Idee - die bloße Tatsache, dass alle Inhalte _internalab Version 10
vorliegen
2
@chuwy stackoverflow.com/a/50255019/918959 <= this one. pip._internalist nicht für den Import konzipiert, kann jedoch beim Import in ein anderes Programm absolut zufällige Aktionen ausführen.
Antti Haapala
3
@AnttiHaapala okay, ich habe es geändert. Ich persönlich mag beide Lösungen nicht, aber ich bin heutzutage weit weg von Python, also vertraue ich Ihrer Meinung.
Chuwy

Antworten:

253

Die offiziell empfohlene Methode zum Installieren von Paketen aus einem Skript besteht darin, die Befehlszeilenschnittstelle von pip über einen Unterprozess aufzurufen. Die meisten anderen hier vorgestellten Antworten werden von pip nicht unterstützt . Darüber hinaus wurde seit pip v10 der gesamte Code pip._internalgenau verschoben, um den Benutzern klar zu machen, dass die programmgesteuerte Verwendung von pip nicht zulässig ist.

Verwenden sys.executableSie diese Option, um sicherzustellen, dass Sie dasselbe aufrufen, das pipder aktuellen Laufzeit zugeordnet ist.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])
Aaron de Windt
quelle
Ein Problem dabei ist, dass für Anfänger unter Windows Python und Pip nicht immer in ihrem Pfad sind und daher eine .py-Datei, auf die doppelklicken könnte, sehr praktisch wäre, während ein Kommentar "pip install xxx" sein kann ziemlich knifflig.
jdpipe
CalledProcessError: Der Befehl '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' gab den Exit-Status 1 ungleich Null zurück.
parvij
383

Sie können auch Folgendes verwenden:

import pip

def install(package):
    if hasattr(pip, 'main'):
        pip.main(['install', package])
    else:
        pip._internal.main(['install', package])

# Example
if __name__ == '__main__':
    install('argh')
Rikard Anglerud
quelle
3
@nbro Sie übergeben Optionen pip.main()wie in der Befehlszeile (jedoch mit jeder Option als separaten Eintrag in der Liste anstelle einer einzelnen Zeichenfolge). Und um anzugeben, welche Version des Pakets Sie möchten, gehen Sie wie in der Befehlszeile vor. Beispiel:pip.main(['install', 'pip==7.1.0'])
Kaos
3
Siehe auch stackoverflow.com/questions/6457794/… , in dem gezeigt wird, wie der Fall behandelt wird, in dem eine Installation fehlschlägt.
P. Myer Nore
25
from pip._internal import main as pipmaindann können Sie pipmain()genau wie die veralteten verwenden, pip.main()siehe stackoverflow.com/questions/43398961/…
Björks Nummer eins Fan
17
es ist jetzt veraltet.
Morse
6
Es ist aus einem bestimmten Grund veraltet und wird nicht mehr empfohlen. siehe pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK
71

Wenn Sie das piperforderliche Paket installieren und nach der Installation importieren möchten , können Sie diesen Code verwenden:

def install_and_import(package):
    import importlib
    try:
        importlib.import_module(package)
    except ImportError:
        import pip
        pip.main(['install', package])
    finally:
        globals()[package] = importlib.import_module(package)


install_and_import('transliterate')

Wenn Sie ein Paket als Benutzer installiert haben, kann das Problem auftreten, dass Sie das Paket nicht einfach importieren können. Siehe So aktualisieren Sie sys.path? für weitere Informationen.

rominf
quelle
4
Irgendeine Idee, wie man das auf Python 3 macht? imp.reload(site)holt michRuntimeError: dictionary changed size during iteration
kgadek
Wo installiert das das Paket, nachdem ich dies getan habe, konnte ich nicht tun pip uninstall <package_name>. Ich kann es immer noch mit deinstallieren pip.main, wollte aber nur wissen, wo das Paket installiert wird.
Ishan Khare
War neugierig. würde das richtig funktionieren, wenn ich es tue : pip install requests[security]? Ich war mir nicht sicher, ob es die Globals richtig definieren würde.
Fallenreaper
4
Veraltet. pip.mainfunktioniert nicht mehr. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim
23

Das sollte funktionieren:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])
Quantum
quelle
1
Ja, es sollte definitiv funktionieren. Aber ich dachte, es gibt einen eleganteren Weg;) Ich werde ein bisschen warten, vielleicht gibt es einen.
Chuwy
1
@ Downvoter: Was genau ist falsch an meiner Antwort? Diese Antwort hat alle OP gewünscht. Es wird nicht einmal eine Shell verwendet.
Quantum
13
Es hängt davon ab, ob die richtige Version von pip zuerst auf dem Pfad ist. Wenn der Benutzer eine alternative Python-Installation ausführt, wird pip anstelle der aktuellen in die erste installiert. Der oben beschriebene Importansatz wird an der richtigen Stelle installiert. Ich habe trotzdem gestimmt, um der Abwertung entgegenzuwirken.
Gary Bishop
6
Abhängig davon, wie das Skript ausgeführt wird, rufen Sie nicht den richtigen Pip auf.
Natim
5
Wenn Sie anrufen [sys.executable, '-m', 'pip', 'install', name], stellen Sie sicher, dass Sie hier den "richtigen" Pip finden.
wim
12

Ich habe @ Aarons Antwort eine Ausnahmebehandlung hinzugefügt.

import subprocess
import sys

try:
    import pandas as pd
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", 'pandas'])
finally:
    import pandas as pd
Sohan Das
quelle
1
schöne Implementierung von Subprozess und Pip, besser als die meisten Lösungen hier
Shantanu Shady
3
Sie überprüfen nicht den Retunr-Wert von, subprocess.calldamit der Code möglicherweise fehlschlägt.
Antti Haapala
5

Sie definieren das abhängige Modul in der setup.py Ihres eigenen Pakets mit der Option "install_requires".

Wenn für Ihr Paket ein Konsolenskript generiert werden muss, können Sie den Einstiegspunkt "console_scripts" verwenden, um ein Wrapper-Skript zu generieren, das im Ordner "bin" (z. B. Ihrer virtualenv-Umgebung) abgelegt wird.

Andreas Jung
quelle
1
Dies ist die richtige Antwort und der einzig sinnvolle Weg, um die Abhängigkeiten eines Python-Projekts zu verwalten. Es funktioniert mit virtualenv, Fabric, Buildout, wie Sie es nennen. Die von @xiaomao beschriebene Methode ist purer Wahnsinn, obwohl sie genau das beantwortet, was das OP verlangt hat.
Lukas Graf
7
Dies ist zwar ein richtiger Rat, beantwortet aber nicht die gestellte Frage
Corey Goldberg
2
Während das Packen ein Thema ist, gibt es viele andere Anwendungsfälle, beispielsweise ein in Python geschriebenes Bereitstellungsskript.
hoefling