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.


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

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

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.


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


23

To powinno działać:

import subprocess

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

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

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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.