Instalowanie modułu python w kodzie

309

Muszę zainstalować pakiet z PyPi bezpośrednio w moim skrypcie. Może jest jakiś moduł lub distutils( distribute, pipetc.) funkcja, która pozwala mi tylko wykonać coś takiego pypi.install('requests')i wnioski zostaną zainstalowane w moim virtualenv.

chuwy
źródło
4
Dlaczego nie zdefiniujesz powiązanego modułu jako zależności w pliku setup.py własnego pakietu?
Andreas Jung,
5
wiesz ... sposób, w jaki to powinno być zrobione ... ale zawsze możesz zawsze os.system ("pip install blah"), ale możesz potrzebować dostępu do sudo ... lepiej, aby uczynić go zależnym w twojej konfiguracji. py
Joran Beasley
2
Czy mógłbyś rozważyć zmianę zaakceptowanej odpowiedzi tutaj? Importowanie pipnigdy nie jest dobrym pomysłem - sam fakt, że cała jego zawartość _internalzaczyna się od wersji 10 ...
Antti Haapala
2
@chuwy stackoverflow.com/a/50255019/918959 <= ten. pip._internalnie jest przeznaczony do importowania, może robić absolutnie losowe rzeczy po zaimportowaniu do innego programu.
Antti Haapala,
3
@AnttiHaapala dobrze, zmieniłem to. Osobiście nie lubię obu rozwiązań, ale obecnie jestem daleko od Pythona, więc ufam twojej opinii.
chuwy

Odpowiedzi:

251

Oficjalnie zalecanym sposobem instalowania pakietów ze skryptu jest wywołanie interfejsu wiersza polecenia pip za pośrednictwem podprocesu. Większość innych odpowiedzi tutaj przedstawionych nie jest obsługiwana przez pip . Co więcej, od pip v10, cały kod został przeniesiony pip._internalwłaśnie do tego w celu wyjaśnienia użytkownikom, że programowe korzystanie z pip jest niedozwolone.

Użyj, sys.executableaby upewnić się, że zadzwonisz tak samo, jak pipw przypadku bieżącego środowiska wykonawczego.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])
Aaron de Windt
źródło
Jednym z problemów jest to, że dla początkujących użytkowników systemu Windows Python i pip nie zawsze znajdują się na PATH, więc plik .py, który można kliknąć dwukrotnie, byłby całkiem wygodny, podczas gdy komentarz „pip install xxx” może być dość trudne.
jdpipe
CalledProcessError: Command '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' zwrócił niezerowy status wyjścia 1.
parvij
381

Możesz także użyć czegoś takiego:

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
źródło
3
@ nbro przekazujesz opcje pip.main()tak, jak w wierszu poleceń (ale z każdą opcją jako osobny wpis na liście zamiast pojedynczego ciągu). Aby określić, którą wersję pakietu chcesz zrobić, zrób to samo, co w wierszu poleceń .. np .:pip.main(['install', 'pip==7.1.0'])
Kaos
3
Zobacz także stackoverflow.com/questions/6457794/… , który pokazuje, jak postępować w przypadku niepowodzenia instalacji.
P. Myer Nore,
24
from pip._internal import main as pipmainmożesz użyć pipmain()tak jak przestarzałe pip.main()patrz stackoverflow.com/questions/43398961/...
fan Bjorks numer jeden
17
jest przestarzałe.
Morse
6
Jest przestarzałe z jakiegoś powodu i nie jest już zalecane. patrz pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK
71

Jeśli chcesz użyć pipdo zainstalowania wymaganego pakietu i zaimportowania go po instalacji, możesz użyć tego kodu:

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

Jeśli zainstalowałeś pakiet jako użytkownik, możesz napotkać problem, którego nie możesz po prostu zaimportować. Zobacz Jak odświeżyć sys.path? po dodatkowe informacje.

rominf
źródło
4
Masz pomysł, jak to zrobić w Pythonie 3? imp.reload(site)dostaje mnieRuntimeError: dictionary changed size during iteration
kgadek
gdzie to instaluje pakiet, po tym, jak to zrobiłem, nie byłem w stanie tego zrobić pip uninstall <package_name>. Nadal mogę go odinstalować, pip.mainale chciałem tylko wiedzieć, gdzie instaluje pakiet?
Ishan Khare,
Był ciekawy. to będzie działać prawidłowo, jeśli mam zrobić: pip install requests[security]? Nie byłem pewien, czy poprawnie zdefiniuje globały poprawnie.
Fallenreaper
4
Przestarzały. pip.mainnie działa. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim
23

To powinno działać:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])
kwant
źródło
1
Tak, to zdecydowanie powinno działać. Ale myślałem, że jest bardziej elegancki sposób;) Będę czekał trochę, może być.
chuwy,
1
@Downvoter: Co dokładnie jest nie tak z moją odpowiedzią? Ta odpowiedź ma wszystkie potrzebne OP. Nawet nie używa powłoki.
kwantowo
13
To zależy od właściwej wersji pipa, która jest pierwsza na ścieżce. Jeśli użytkownik uruchamia alternatywną instalację Pythona, pip zainstaluje się w pierwszej zamiast bieżącej. Powyższe podejście do importowania zostanie zainstalowane we właściwym miejscu. Mimo to głosowałem za odrzuceniem głosowania w dół.
GaryBishop
6
W zależności od tego, jak działa skrypt, nie będziesz wywoływał właściwej pip.
Natim
5
Dzwonienie [sys.executable, '-m', 'pip', 'install', name]upewnia się, że otrzymujesz „właściwą” pipę tutaj.
wim
12

dodałem obsługę wyjątków do odpowiedzi @ Aarona.

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
źródło
1
fajna implementacja podprocesu i pipa, lepsza niż większość rozwiązań tutaj
Shantanu Shady
3
Nie sprawdzasz wartości parametru retunr, subprocess.callwięc kod może się nie powieść.
Antti Haapala,
5

Moduł zależny definiujesz w pliku setup.py własnego pakietu za pomocą opcji „install_requires”.

Jeśli twój pakiet wymaga wygenerowania skryptu konsoli, możesz użyć punktu wejścia „script_scripts”, aby wygenerować skrypt otoki, który zostanie umieszczony w folderze „bin” (np. W środowisku virtualenv).

Andreas Jung
źródło
1
To jest poprawna odpowiedź i jedyny rozsądny sposób zarządzania zależnościami projektów Python. Będzie działał z virtualenv, Fabric, buildout, nazwiesz go. Metoda opisana przez @xiaomao, mimo że odpowiada dokładnie na to, o co poprosił OP, jest czystym szaleństwem.
Lukas Graf,
7
chociaż jest to właściwa rada, nie odpowiada na zadane pytanie
Corey Goldberg,
2
Chociaż pakowanie jest tematem, istnieje wiele innych przypadków użycia, na przykład skrypt wdrażania napisany w Pythonie.
hoefling