Cài đặt mô-đun python trong mã


310

Tôi cần cài đặt một gói từ PyPi ngay trong kịch bản của mình. Có thể có một số mô-đun hoặc tính năng distutils( distribute, pipv.v.) cho phép tôi thực hiện một cái gì đó giống như pypi.install('requests')và các yêu cầu sẽ được cài đặt vào virtualenv của tôi.


4
Tại sao bạn không xác định mô-đun liên quan là phụ thuộc trong setup.py của gói của riêng bạn?
Andreas Jung

5
bạn biết ... cách thực sự cần phải được thực hiện ... nhưng bạn luôn có thể os.system ("pip install blah") nhưng bạn có thể cần truy cập sudo ... tốt hơn để biến nó thành một phụ thuộc trong thiết lập của bạn. py
Joran Beasley

2
Bạn sẽ xem xét thay đổi câu trả lời được chấp nhận ở đây? Nhập khẩu pipkhông bao giờ là một ý tưởng hay - thực tế là tất cả nội dung của nó đều _internalbắt đầu từ phiên bản 10 ...
Antti Haapala

2
@chuwy stackoverflow.com/a/50255019/918959 <= cái này. pip._internalkhông được thiết kế để có thể nhập được, nó có thể thực hiện những điều hoàn toàn ngẫu nhiên khi được nhập trong chương trình khác.
Antti Haapala

3
@AnttiHaapala được rồi, tôi đã thay đổi nó. Cá nhân tôi không thích cả hai giải pháp, nhưng tôi ở rất xa Python ngày nay, vì vậy tôi tin tưởng ý kiến ​​của bạn.
chuwy

Câu trả lời:


254

Cách chính thức được đề xuất để cài đặt các gói từ tập lệnh là bằng cách gọi giao diện dòng lệnh của pip thông qua một quy trình con. Hầu hết các câu trả lời khác được trình bày ở đây không được hỗ trợ bởi pip . Hơn nữa, kể từ pip v10, tất cả các mã đã được chuyển đến pip._internalchính xác để làm cho người dùng rõ ràng rằng việc sử dụng pip theo chương trình không được phép.

Sử dụng sys.executableđể đảm bảo rằng bạn sẽ gọi tương tự pipliên quan đến thời gian chạy hiện tại.

import subprocess
import sys

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

Một vấn đề với điều này là, đối với người dùng mới làm quen trên Windows, python và pip không phải lúc nào cũng có trên PATH của họ, và do đó, một tệp .py có thể nhấp đúp sẽ khá thuận tiện, trong khi đó có thể nhận xét "pip install xxx" khá khó khăn
jdpipe

CalledProcessError: Command '[' C: \\ \\ ProgramData Anaconda3 \\ pythonw.exe ' '-m', 'pip', 'cài đặt', 'googleapiclient']' tình trạng trở khác không thoát 1.
parvij

383

Bạn cũng có thể sử dụng một cái gì đó như:

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 bạn chuyển các tùy chọn pip.main()như trên dòng lệnh (nhưng với mỗi tùy chọn là một mục riêng biệt trong danh sách, thay vì một chuỗi đơn). Và để chỉ định phiên bản nào của gói bạn muốn, hãy thực hiện tương tự như trên dòng lệnh .. ví dụ:pip.main(['install', 'pip==7.1.0'])
Kaos

3
Xem thêm stackoverflow.com/questions/6457794/ , hướng dẫn cách xử lý trường hợp cài đặt không thành công.
P. Myer Nore

25
from pip._internal import main as pipmainsau đó bạn có thể sử dụng pipmain()giống như phần không dùng nữa, pip.main()xem stackoverflow.com/questions/43398961/
Khăn

17
nó mất giá bây giờ
Morse

6
Nó không được chấp nhận vì một lý do & không được khuyến khích nữa. xem pip.pypa.io/en/latest/user_guide/#USE-pip-from-your-program
NBK

71

Nếu bạn muốn sử dụng pipđể cài đặt gói yêu cầu và nhập nó sau khi cài đặt, bạn có thể sử dụng mã này:

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

Nếu bạn đã cài đặt một gói như một người dùng, bạn có thể gặp phải vấn đề là bạn không thể chỉ nhập gói. Xem cách làm mới sys.path? Để biết thêm thông tin chi tiết.


4
Bất kỳ ý tưởng làm thế nào để làm điều đó trên Python 3? imp.reload(site)giúp tôiRuntimeError: dictionary changed size during iteration
kgadek

Trường hợp này cài đặt gói, sau khi tôi đã làm điều này, tôi đã không thể làm pip uninstall <package_name>. Tôi vẫn có thể gỡ cài đặt nó bằng cách sử dụng pip.mainnhưng chỉ muốn biết nó cài đặt gói ở đâu?
Ishan Khare

Tò mò. điều này sẽ làm việc đúng nếu tôi làm : pip install requests[security]? Tôi không chắc chắn nếu nó sẽ xác định đúng toàn cầu.
Fallenreaper

4
Đã lỗi thời. pip.maincông việc ngắn hạn. pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program
wim

23

Điều này sẽ làm việc:

import subprocess

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

1
Vâng, nó chắc chắn nên hoạt động. Nhưng tôi nghĩ có cách thanh lịch hơn;) Tôi sẽ đợi một chút, có thể là có.
chuwy

1
@Downvoter: Chính xác thì câu trả lời của tôi là gì? Câu trả lời này có tất cả những gì OP muốn. Nó thậm chí không sử dụng vỏ.
lượng tử

13
Nó phụ thuộc vào phiên bản đúng của pip là đầu tiên trên đường dẫn. Nếu người dùng đang chạy cài đặt python thay thế, pip sẽ cài đặt vào cái đầu tiên thay vì cái hiện tại. Cách tiếp cận nhập khẩu ở trên sẽ cài đặt đúng nơi. Dù sao thì tôi cũng ủng hộ để bỏ phiếu.
GaryBishop

6
Tùy thuộc vào cách tập lệnh đang chạy, bạn sẽ không gọi đúng pip.
Natim

5
Gọi [sys.executable, '-m', 'pip', 'install', name]là đảm bảo để có được pip "đúng" ở đây.
wim

12

tôi đã thêm một số xử lý ngoại lệ vào câu trả lời của @ Aaron.

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
triển khai tốt quy trình con và pip, tốt hơn hầu hết các giải pháp ở đây
Chaianu Shady

3
Bạn không kiểm tra giá trị retunr của subprocess.callmã để mã có thể bị lỗi.
Antti Haapala

5

Bạn xác định mô-đun phụ thuộc bên trong setup.py của gói của riêng bạn với tùy chọn "install_Vquires".

Nếu gói của bạn cần phải có một số tập lệnh console được tạo thì bạn có thể sử dụng điểm nhập "console_scripts" để tạo tập lệnh bao bọc sẽ được đặt trong thư mục 'bin' (ví dụ: môi trường virtualenv của bạn).


1
Đây là câu trả lời đúng và là cách hợp lý duy nhất để quản lý các phụ thuộc của dự án Python. Nó sẽ hoạt động với virtualenv, Fabric, buildout, bạn đặt tên cho nó. Phương pháp được mô tả bởi @xiaomao, mặc dù trả lời chính xác những gì OP yêu cầu, là sự điên rồ thuần túy.
Lukas Graf

7
trong khi đây là lời khuyên phù hợp, nó không trả lời câu hỏi được hỏi
Corey Goldberg

2
Mặc dù bao bì là một chủ đề, có rất nhiều trường hợp sử dụng khác, ví dụ như một kịch bản triển khai được viết bằng python.
cuốc vào
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.