Tôi có một tệp requirements.txt
với danh sách các gói cần thiết cho môi trường ảo của tôi. Có thể tìm hiểu xem tất cả các gói được đề cập trong tệp có hiện diện hay không. Nếu một số gói bị thiếu, làm thế nào để tìm ra đó là các gói bị thiếu?Làm thế nào để kiểm tra xem Python của tôi có tất cả các gói cần thiết không?
Trả lời
Các pythonic cách thực hiện là qua pkg_resources
API. Các yêu cầu được viết theo một định dạng được hiểu bởi setuptools. Ví dụ:
Werkzeug>=0.6.1
Flask
Django>=1.3
Đoạn mã ví dụ:
import pkg_resources
from pkg_resources import DistributionNotFound, VersionConflict
# dependencies can be any iterable with strings,
# e.g. file line-by-line iterator
dependencies = [
'Werkzeug>=0.6.1',
'Flask>=0.9',
]
# here, if a dependency is not met, a DistributionNotFound or VersionConflict
# exception is thrown.
pkg_resources.require(dependencies)
Bạn có thể chạy pip freeze
để xem những gì bạn đã cài đặt và so sánh với tệp requirements.txt
của bạn.
Nếu bạn muốn cài đặt các mô-đun bị thiếu, bạn có thể chạy pip install -r requirements.txt
và cài đặt bất kỳ mô-đun bị thiếu nào và cho bạn biết ở cuối mô-đun nào bị thiếu và cài đặt.
Nếu requirements.txt giống như:
django
oursql
sys
notexistingmodule
Sau đó kịch bản sau đây sẽ cho bạn biết các module đang thiếu:
#!/usr/bin/python3
fname = 'requirements.txt'
with open(fname, 'r', encoding='utf-8') as fhd:
for line in fhd:
try:
exec("import " + line)
except:
print("[ERROR] Missing module:", line)
này sẽ in:
[ERROR] Missing module: notexistingmodule
Điều này sẽ thất bại nếu requirements.txt chứa thông tin phiên bản, ví dụ: 'django == 1.5.1' –
Thật vậy. Và nó sẽ thất bại nếu mô-đun được liệt kê trong một dòng quá. Nó sẽ làm việc, như đã nêu, nếu requirements.txt liệt kê một mô-đun trên mỗi dòng. –
Bạn có chắc chắn rằng tên gói giống với tên mô-đun không? – warvariuc
Bạn có thể tạo một virtualenv với quyền truy cập vào các trang web gói hệ thống và kiểm tra kiểm tra xem gói (hoặc phụ thuộc khác) được cài đặt hay không. Bằng cách này các gói không thực sự được cài đặt (nếu bạn chỉ muốn kiểm tra). Một ví dụ sử dụng virtualenv wrapper sẽ là:
$ cat requirements.txt
requests
simplejson
$ mkvirtualenv --system-site-packages test
Running virtualenv with interpreter /usr/bin/python2
New python executable in test/bin/python2
Also creating executable in test/bin/python
Installing setuptools, pip...done.
$ pip install -r requirements.txt
Downloading/unpacking requests (from -r requirements.txt (line 1))
Downloading requests-2.10.0-py2.py3-none-any.whl (506kB): 506kB downloaded
Requirement already satisfied (use --upgrade to upgrade): simplejson in /usr/lib/python2.7/dist-packages (from -r requirements.txt (line 2))
Installing collected packages: requests
Successfully installed requests
Cleaning up...
$ pip install -r requirements.txt
Requirement already satisfied (use --upgrade to upgrade): requests in /home/yucer/.virtualenvs/test/lib/python2.7/site-packages (from -r requirements.txt (line 1))
Requirement already satisfied (use --upgrade to upgrade): simplejson in /usr/lib/python2.7/dist-packages (from -r requirements.txt (line 2))
Cleaning up...
$ deactivate
$ rmvirtualenv test
Removing test...
Dựa trên answer by Zaur, giả sử bạn thực sự sử dụng một tập tin requirements.txt
, bạn có thể muốn có một thử nghiệm đơn vị, có lẽ trong tests/test_requirements.py
, đó khẳng định sự sẵn có của các gói.
Cách tiếp cận chung là:
import pathlib
import unittest
import pip
import pkg_resources
class TestRequirements(unittest.TestCase):
def test_requirements(self): # pylint: disable=no-self-use
"""Recursively confirm that requirements are available.
This implementation is tested to be compatible with pip 9.0.1.
"""
requirements_path = pathlib.Path(__file__).parents[1]/'requirements.txt'
requirements = pip.req.parse_requirements(str(requirements_path), session=pip.download.PipSession())
requirements = [str(r.req) for r in requirements]
pkg_resources.require(requirements)
Lưu ý rằng câu trả lời này sử dụng pathlib
trong đó có sẵn trong Python 3 nhưng không phải trong Python 2. Nếu sử dụng Python 2, đầu tiên cài đặt backport cho nó đó là pathlib2
.
Đây thực sự là một ý tưởng tuyệt vời! –
Là tiền thưởng, điều này tự động phát hiện đệ quy các yêu cầu phiên bản xung đột - những điều này sẽ không thỏa mãn. –