Installazione del modulo Python nel codice


310

Devo installare un pacchetto da PyPi direttamente nel mio script. Forse c'è qualche modulo o funzione distutils( distribute, pipecc.) Che mi permette di eseguire qualcosa del genere pypi.install('requests')e le richieste verranno installate nel mio virtualenv.


4
Perché non definisci il modulo correlato come dipendenza in setup.py del tuo pacchetto?
Andreas Jung,

5
sai ... il modo in cui dovrebbe effettivamente essere fatto ... ma potresti sempre os.system ("pip install blah") ma potresti aver bisogno dell'accesso sudo ... meglio per renderlo una dipendenza nella tua configurazione. py
Joran Beasley l'

2
Considereresti di cambiare la risposta accettata qui? L'importazione pipnon è mai una buona idea - il semplice fatto che tutto il suo contenuto sia a _internalpartire dalla versione 10 ...
Antti Haapala il

2
@chuwy stackoverflow.com/a/50255019/918959 <= questo. pip._internalnon è progettato per essere importabile, può fare cose assolutamente casuali se importato in un altro programma.
Antti Haapala,

3
@AnttiHaapala ok, l'ho cambiato. Personalmente non mi piacciono entrambe le soluzioni, ma in questi giorni sono lontano da Python, quindi mi fido della tua opinione.
chuwy

Risposte:


255

Il modo ufficialmente raccomandato per installare i pacchetti da uno script consiste nel chiamare l'interfaccia della riga di comando di pip tramite un sottoprocesso. La maggior parte delle altre risposte qui presentate non sono supportate da pip . Inoltre, da pip v10, tutto il codice è stato spostato pip._internalin modo preciso per chiarire agli utenti che l'uso programmatico di pip non è consentito.

Usare sys.executableper assicurarsi di chiamare lo stesso pipassociato al runtime corrente.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

Un problema con questo è che, per gli utenti alle prime armi su Windows, Python e Pip non sono sempre sul loro PERCORSO, e quindi un file .py che può essere fatto doppio clic sarebbe abbastanza conveniente, mentre un commento "pip install xxx" può essere abbastanza complicato.
jdpipe,

CalledProcessError: il comando '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' ha restituito uno stato di uscita diverso da zero 1.
parvij

383

Puoi anche usare qualcosa come:

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')

3
@nbro si passano le opzioni pip.main()come si farebbe sulla riga di comando (ma con ciascuna opzione come voce separata nell'elenco, anziché una singola stringa). E per specificare quale versione del pacchetto si desidera, fare lo stesso della riga di comando. Es:pip.main(['install', 'pip==7.1.0'])
Kaos

3
Vedi anche stackoverflow.com/questions/6457794/… , che mostra come gestire il caso in cui l'installazione non riesce.
P. Myer Nore,

25
from pip._internal import main as pipmainquindi è possibile utilizzare pipmain()proprio come il deprecato pip.main()vedere stackoverflow.com/questions/43398961/...
numero Bjork un ventilatore

17
ora è deprecato.
Morse,

6
È deprecato per un motivo e non è più raccomandato. vedi pip.pypa.io/it/latest/user_guide/#using-pip-from-your-program
NBK

71

Se si desidera utilizzare pipper installare il pacchetto richiesto e importarlo dopo l'installazione, è possibile utilizzare questo codice:

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')

Se hai installato un pacchetto come utente, puoi riscontrare il problema che non puoi semplicemente importare il pacchetto. Vedi Come aggiornare sys.path? per ulteriori informazioni.


4
Qualche idea su come farlo su Python 3? imp.reload(site)mi prendeRuntimeError: dictionary changed size during iteration
kgadek il

dove installa il pacchetto, dopo averlo fatto, non sono stato in grado di farlo pip uninstall <package_name>. Posso ancora disinstallarlo usando pip.mainma volevo solo sapere dove installa il pacchetto?
Ishan Khare,

Era curioso. funzionerebbe correttamente se lo facessi pip install requests[security]:? Non ero sicuro che avrebbe definito correttamente i globi.
Fallenreaper


22

Questo dovrebbe funzionare:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])

1
Sì, dovrebbe sicuramente funzionare. Ma ho pensato che ci fosse un modo più elegante;) Aspetterò un po ', potrebbe esserci.
robusto

1
@Downvoter: cosa c'è di sbagliato nella mia risposta? Questa risposta ha tutti i PO desiderati. Non usa nemmeno una shell.
quantum

13
Dipende dal fatto che la versione corretta di pip sia la prima nel percorso. Se l'utente esegue un'installazione Python alternativa, pip verrà installato nel primo anziché in quello corrente. L'approccio di importazione sopra verrà installato nel posto giusto. Ho comunque votato per contrastare il voto negativo.
GaryBishop

6
A seconda di come viene eseguito lo script, non si chiamerà il pip giusto.
Natim

5
La chiamata si [sys.executable, '-m', 'pip', 'install', name]sta assicurando di ottenere il pip "giusto" qui.
mercoledì

12

ho aggiunto alcune eccezioni alla risposta di @ Aaron.

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

1
bella implementazione di sottoprocesso e pip, meglio della maggior parte delle soluzioni qui
Shantanu Shady,

3
Non stai controllando il valore di riaccensione di subprocess.callquindi il codice potrebbe non riuscire.
Antti Haapala,

5

Definisci il modulo dipendente all'interno di setup.py del tuo pacchetto con l'opzione "install_requires".

Se il pacchetto deve avere alcuni script di console generati, è possibile utilizzare il punto di ingresso "console_scripts" per generare uno script wrapper che verrà inserito nella cartella "bin" (ad es. Ambiente virtualenv).


1
Questa è la risposta corretta e l'unico modo sensato per gestire le dipendenze di un progetto Python. Funzionerà con virtualenv, Fabric, buildout, tu lo chiami. Il metodo descritto da @xiaomao, pur rispondendo esattamente a ciò che l'OP ha chiesto, è pura follia.
Lukas Graf,

7
mentre questo è un consiglio adeguato, non risponde alla domanda posta
Corey Goldberg,

2
Mentre il packaging è un argomento, ci sono molti altri casi d'uso, ad esempio uno script di distribuzione scritto in Python.
hoefling
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.