2013-06-24 11 views
10

Zakładając, że masz już zainstalowaną pip lub easy_install na swojej dystrybucji Pythona, chciałbym wiedzieć, w jaki sposób mogę zainstalować wymagany pakiet w katalogu użytkownika z samego skryptu.Jak zainstalować brakujący pakiet Pythona z poziomu skryptu, który tego potrzebuje?

Z tego co wiem, pip jest również moduł Pythona, więc rozwiązanie powinno wyglądać następująco:

try: 
    import zumba 
except ImportError: 
    import pip 
    # ... do "pip install --user zumba" or throw exception <-- how? 
    import zumba 

Co mi brakuje robi „pip zainstalować --user zumba” od wewnątrz pytona, nie wiem chcesz to zrobić, używając os.system(), ponieważ może to spowodować inne problemy.

Zakładam, że jest to możliwe ...

+1

Jak o tym rozwiązaniu: http://stackoverflow.com/questions/12332975/installing-python-module-within-code –

+2

myślę, że to byłoby bardzo niepożądana praktyka kodowania poza skryptem instalacyjnym. Ja (jak sądzę, że większość ludzi) nie chciałby/zaufać programowi, który prowadzę, który zmienia moje środowisko. Narzędzia takie jak pip i virtualenv są właśnie tam, aby "użytkownik" miał kontrolę nad tym, jaki pakiet jest zainstalowany, do której wersji. Nie jestem ekspertem od distutils, ale wiem, że ma on listę wymagań wstępnych dla każdej paczki. Jeśli jest to tylko na własny użytek, prawdopodobnie możesz zmarnować trochę tego kodu. – Joop

+0

Dzięki wam, działa idealnie. Na marginesie jest to dobre rozwiązanie dla samodzielnych skryptów, a nie modułów/pakietów. – sorin

Odpowiedz

14

Dzięki @Joop udało mi się przyjść się z właściwą odpowiedzią.

try: 
    import zumba 
except ImportError: 
    import pip 
    pip.main(['install', '--user', 'zumba']) 
    import zumba 

Jedna ważna uwaga jest taka, że ​​będzie działać bez wymagania uprawnień administratora, ponieważ zainstaluje moduł w katalogu użytkownika.

Nie wiem, czy zadziała w przypadku modułów binarnych lub takich, które wymagałyby kompilacji, ale wyraźnie sprawdza się w przypadku modułów czysto-pythonowych.

Teraz możesz pisać samodzielne skrypty i nie martwić się o zależności.

+0

To działało dla mnie, aby zainstalować 'boto3' w serwisie PythonAnywhere. Wygląda na to, że pip.main() jest tylko otoką w narzędziu wiersza poleceń, zamiast oferować API. Miło, brzydko, ale funkcjonalnie, jak sądzę. Otrzymałem komunikat "odmowa dostępu", dopóki nie dodałem '--user'. –

1

Pragnę zauważyć, że bieżąca zaakceptowana odpowiedź może spowodować kolizję nazwy aplikacji. Importowanie z przestrzeni nazw aplikacji nie daje pełnego obrazu tego, co jest zainstalowane w systemie.

Lepszym sposobem byłoby:

import pip 

packages = [package.project_name for package in pip.get_installed_distributions()] 

if 'package' not in packages: 
    pip.main(['install', 'package']) 
Powiązane problemy