Memasang modul python dalam kode

310

Saya perlu menginstal paket dari PyPi langsung dalam skrip saya. Mungkin ada beberapa modul atau fitur distutils( distribute, pipdll.) Yang memungkinkan saya untuk menjalankan sesuatu seperti pypi.install('requests')dan permintaan akan diinstal ke dalam virtualenv saya.

chuwy
sumber
4
Mengapa Anda tidak mendefinisikan modul terkait sebagai dependensi di setup.py dari paket Anda sendiri?
Andreas Jung
5
Anda tahu ... cara yang seharusnya dilakukan ... tetapi Anda selalu dapat menggunakan sistem ("pip install bla") tetapi Anda mungkin memerlukan akses sudo ... lebih baik untuk membuatnya menjadi ketergantungan pada pengaturan Anda. py
Joran Beasley
2
Apakah Anda mempertimbangkan untuk mengubah jawaban yang diterima di sini? Mengimpor piptidak pernah merupakan ide yang baik - fakta bahwa semua isinya _internalmulai dari versi 10 ...
Antti Haapala
2
@chuwy stackoverflow.com/a/50255019/918959 <= yang ini. pip._internaltidak dirancang untuk dapat diimpor, ia dapat melakukan hal-hal yang benar-benar acak ketika diimpor dalam program lain.
Antti Haapala
3
@AnttiHaapala oke saya mengubahnya. Saya pribadi tidak suka kedua solusi, tapi saya jauh dari Python hari ini, jadi saya percaya pendapat Anda.
chuwy

Jawaban:

254

Cara yang disarankan secara resmi untuk menginstal paket dari skrip adalah dengan memanggil antarmuka baris perintah pip melalui subproses. Sebagian besar jawaban lain yang disajikan di sini tidak didukung oleh pip . Selain itu sejak pip v10, semua kode telah dipindahkan ke pip._internaltepatnya untuk menjelaskan kepada pengguna bahwa penggunaan program pip tidak diizinkan.

Gunakan sys.executableuntuk memastikan bahwa Anda akan memanggil yang sama pipterkait dengan runtime saat ini.

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])
Aaron de Windt
sumber
Satu masalah dengan ini adalah bahwa, untuk pengguna pemula di Windows, python dan pip tidak selalu di PATH mereka, dan file .py yang bisa diklik dua kali akan cukup nyaman, sedangkan komentar "pip install xxx" dapat cukup rumit.
jdpipe
Disebut CalledProcessError: Perintah '[' C: \\ ProgramData \\ Anaconda3 \\ pythonw.exe ',' -m ',' pip ',' install ',' googleapiclient ']' mengembalikan status keluar bukan nol 1.
parvij
383

Anda juga dapat menggunakan sesuatu seperti:

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
sumber
3
@nbro Anda meneruskan opsi pip.main()seperti yang Anda lakukan pada baris perintah (tetapi dengan setiap opsi sebagai entri terpisah dalam daftar, alih-alih string tunggal). Dan untuk menentukan versi paket yang Anda inginkan, lakukan hal yang sama seperti pada baris perintah .. mis:pip.main(['install', 'pip==7.1.0'])
Kaos
3
Lihat juga stackoverflow.com/questions/6457794/… , yang menunjukkan cara menangani kasus di mana instalasi gagal.
P. Myer Nore
25
from pip._internal import main as pipmainmaka Anda dapat menggunakan pipmain()seperti yang dihentikan pip.main()lihat stackoverflow.com/questions/43398961/...
Bjorks nomor satu penggemar
17
itu rusak sekarang.
Morse
6
Sudah usang karena suatu alasan & tidak direkomendasikan lagi. lihat pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
NBK
71

Jika Anda ingin menggunakan pipuntuk menginstal paket yang diperlukan dan mengimpornya setelah instalasi, Anda dapat menggunakan kode ini:

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

Jika Anda menginstal paket sebagai pengguna, Anda dapat menemukan masalah yang tidak bisa Anda impor saja. Lihat Cara menyegarkan sys.path? untuk informasi tambahan.

rominf
sumber
4
Adakah yang tahu bagaimana melakukannya di Python 3? imp.reload(site)membuat sayaRuntimeError: dictionary changed size during iteration
kgadek
di mana ini menginstal paket, setelah saya melakukan ini, saya tidak dapat melakukannya pip uninstall <package_name>. Saya masih dapat menghapus instalannya pip.maintetapi hanya ingin tahu di mana ia menginstal paket?
Ishan Khare
Penasaran. apakah ini akan berfungsi dengan baik jika saya lakukan pip install requests[security]:? Saya tidak yakin apakah itu akan mendefinisikan global dengan benar.
Fallenreaper
4
Ketinggalan jaman. pip.maintidak lagi berfungsi. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim
22

Ini seharusnya bekerja:

import subprocess

def install(name):
    subprocess.call(['pip', 'install', name])
kuantum
sumber
1
Ya itu pasti harus bekerja. Tapi saya pikir ada cara yang lebih elegan;) Saya akan menunggu sedikit, mungkin ada.
chuwy
1
@Downvoter: Apa yang salah dengan jawaban saya? Jawaban ini memiliki semua yang diinginkan OP. Bahkan tidak menggunakan shell.
quantum
13
Itu tergantung pada versi yang benar dari pip menjadi yang pertama di jalan. Jika pengguna menjalankan instalasi python alternatif, pip akan menginstal yang pertama bukan yang sekarang. Pendekatan impor di atas akan dipasang di tempat yang tepat. Saya tetap memilih untuk melawan suara turun.
GaryBishop
6
Tergantung pada bagaimana skrip berjalan Anda tidak akan memanggil pip yang tepat.
Natim
5
Memanggil [sys.executable, '-m', 'pip', 'install', name]memastikan untuk mendapatkan pip "benar" di sini.
wim
12

Saya menambahkan beberapa pengecualian menangani jawaban @ Harun.

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
sumber
1
implementasi yang bagus dari subproses dan pip, lebih baik daripada kebanyakan solusi di sini
Shantanu Shady
3
Anda tidak memeriksa nilai retunr subprocess.callsehingga kode mungkin gagal.
Antti Haapala
5

Anda mendefinisikan modul dependen di dalam setup.py dari paket Anda sendiri dengan opsi "install_requires".

Jika paket Anda perlu membuat beberapa skrip konsol yang dihasilkan, maka Anda dapat menggunakan titik masuk "console_scripts" untuk menghasilkan skrip pembungkus yang akan ditempatkan dalam folder 'bin' (misalnya lingkungan virtualenv Anda).

Andreas Jung
sumber
1
Ini adalah jawaban yang benar dan satu-satunya cara yang masuk akal untuk mengelola dependensi proyek Python. Ini akan bekerja dengan virtualenv, Fabric, buildout, apa saja. Metode yang dijelaskan oleh @xiaomao, meskipun menjawab dengan tepat apa yang diminta OP, adalah kegilaan murni.
Lukas Graf
7
sementara ini adalah saran yang tepat, itu tidak menjawab pertanyaan yang diajukan
Corey Goldberg
2
Meskipun pengemasan adalah topik, ada banyak kasus penggunaan lain, misalnya skrip penerapan yang ditulis dengan python.
hoefling