Встановлення модуля python в коді


310

Мені потрібно встановити пакет з PyPi прямо в рамках мого сценарію. Можливо, є якийсь модуль або distutils( distributeі pipт.д.) функція, яка дозволяє мені просто виконати щось на кшталт pypi.install('requests')і запити будуть встановлені в мою virtualenv.


4
Чому ви не визначите відповідний модуль як залежність у setup.py вашого власного пакета?
Андреас Юнг

5
Ви знаєте ... так, як це насправді повинно бути зроблено ... але ви завжди можете os.system ("піп встановити благ"), але вам може знадобитися доступ до судо ... краще просто зробити це залежністю у ваших налаштуваннях. py
Joran Beasley

2
Чи могли б ви тут змінити прийняту відповідь? Імпорт pipніколи не є доброю ідеєю - сам факт того, що весь його вміст _internalпочинається з версії 10 ...
Антті

2
@chuwy stackoverflow.com/a/50255019/918959 <= цей. pip._internalне призначений для імпорту, він може робити абсолютно випадкові речі при імпорті в іншу програму.
Антті

3
@AnttiHaapala добре, я змінив це. Мені особисто не подобаються обидва рішення, але я сьогодні далеко від Python, тому я довіряю вашій думці.
chuwy

Відповіді:


253

Офіційно рекомендований спосіб встановлення пакетів зі скрипту - виклик інтерфейсу командного рядка pip через підпроцес. Більшість інших відповідей, представлених тут, не підтримуються через pip . Крім того, з моменту pip v10, весь код переміщено pip._internalсаме для того, щоб зрозуміти користувачам, що програмне використання pip заборонено.

Використовуйте sys.executableдля того, щоб ви зателефонували тим самим, pipпов’язаним із поточним часом виконання.

import subprocess
import sys

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

Одне з цього питання полягає в тому, що для початківців користувачів в Windows, python і pip не завжди є їх PATH, і тому файл .py, який можна було двічі клацнути, був би досить зручним, тоді як коментар "pip install xxx" може бути досить хитро.
jdpipe

CalledProcessError: Command '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' повернув ненульовий статус виходу 1.
Parvij

383

Ви також можете використовувати щось на кшталт:

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 ви передаєте параметри так, pip.main()як і в командному рядку (але кожен параметр є окремим записом у списку замість однієї рядка). І щоб вказати, яку саме версію пакету ви хочете, зробіть те саме, що і в командному рядку. Наприклад:pip.main(['install', 'pip==7.1.0'])
Kaos

3
Дивіться також stackoverflow.com/questions/6457794/… , де показано, як обробляти випадок, коли встановлення не вдається.
P. Myer Nore

25
from pip._internal import main as pipmainто ви можете використовувати pipmain()так само , як йдуть pip.main()см stackoverflow.com/questions/43398961 / ...
Bjorks номер один вентилятор

17
його застаріле зараз.
Морзе

6
Це застаріло з причини і більше не рекомендується. дивіться pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK

71

Якщо ви хочете використовувати pipвстановити необхідний пакет та імпортувати його після встановлення, ви можете використовувати цей код:

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

Якщо ви встановили пакунок як користувач, ви можете зіткнутися з проблемою, що ви не можете просто імпортувати пакет. Див. Як оновити sys.path? для отримання додаткової інформації.


4
Будь-яка ідея, як це зробити на Python 3? imp.reload(site)отримує менеRuntimeError: dictionary changed size during iteration
kgadek

де це встановити пакет, після того як я це зробив, я не зміг цього зробити pip uninstall <package_name>. Я все ще можу видалити його за допомогою, pip.mainале просто хотів знати, де він встановлює пакет?
Ішан Харе

Був цікавий. Чи буде це справно, якщо я це роблю pip install requests[security]:? Я не був впевнений, чи правильно він визначить глобальну точку.
Fallenreaper

4
Застаріла. pip.mainбільше не працює. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim

23

Це має працювати:

import subprocess

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

1
Так, це безумовно повинно працювати. Але я подумав, що є більш елегантний спосіб;) Я трохи зачекаю, може, є.
chuwy

1
@Downvoter: Що конкретно не відповідає моїй відповіді? У цій відповіді хотіли всі ОП. Він навіть не використовує оболонку.
квантовий

13
Це залежить від правильної версії pip, яка є першою на шляху. Якщо користувач виконує альтернативну установку python, pip встановиться у перший замість поточного. Вищенаведений підхід імпорту встановиться в потрібному місці. Я все-таки виступав проти того, щоб проголосувати проти.
GaryBishop

6
Залежно від того, як виконується сценарій, ви не будете викликати правильний піп.
Натим

5
Виклик [sys.executable, '-m', 'pip', 'install', name]переконайтеся, що тут ви знайдете "правильний" піп.
Вім

12

Я додав відповідь на обробку виключень до відповіді @ Аарона.

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
приємна реалізація підпроцесу та pip, краще, ніж більшість рішень тут
Shantanu Shady

3
Ви не перевіряєте значення retunr, subprocess.callтому код може вийти з ладу.
Антті

5

Ви визначаєте залежний модуль всередині setup.py вашого власного пакета за допомогою параметра "install_requires".

Якщо у вашому пакеті повинен бути створений певний консольний скрипт, ви можете використовувати точку входу "console_scripts", щоб створити скрипт для обгортки, який буде розміщений у папці "bin" (наприклад, у вашому середовищі virtualenv).


1
Це правильна відповідь і єдиний розумний спосіб управління залежностями проектів Python. Він буде працювати з virtualenv, Fabric, buildout, ви його називаєте. Метод, описаний @xiaomao, незважаючи на те, що відповідати саме на те, що просив ОП, - це чисте безумство.
Лукас Граф

7
Хоча це правильна порада, вона не відповідає на поставлене запитання
Corey Goldberg

2
Хоча упаковка є темою, є багато інших випадків використання, наприклад, сценарій розгортання, написаний на python.
гофлінг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.