2011-09-18 36 views
12

Do thiếu sự hỗ trợ cho một số thư viện tôi muốn sử dụng, tôi đã chuyển một số phát triển Python từ Windows sang phát triển Linux. Tôi đã dành phần lớn thời gian trong ngày để làm quen với phụ thuộc.Làm thế nào để đối phó với Linux/Python phụ thuộc?

Câu hỏi đặt ra

Bất cứ khi nào tôi nhặt Linux, tôi thường gặp phải một số loại vấn đề phụ thuộc, thường với các thư viện phát triển, cho dù họ đang được cài đặt qua apt-get, easy_install hoặc pip. Tôi có thể lãng phí ngày về những gì nên được nhiệm vụ đơn giản, chi tiêu lâu hơn vào việc thư viện để làm việc hơn là viết mã. Tôi có thể tìm hiểu về chiến lược xử lý các loại vấn đề này thay vì googling không mục đích cho ai đó gặp phải vấn đề tương tự trước đây?


Một ví dụ

Chỉ cần một ví dụ: tôi muốn tạo ra một số mã QR. Vì vậy, tôi nghĩ rằng tôi muốn sử dụng github.com/bitly/pyqrencode được dựa trên pyqrcode.sourceforge.net nhưng được cho là không có phụ thuộc Java. Có những người khác (pyqrnative, github.com/Arachnid/pyqrencode) nhưng có vẻ như đặt cược tốt nhất cho nhu cầu của tôi.

Vì vậy, tôi thấy các gói trên pypi và nghĩ rằng sử dụng đó sẽ làm cho cuộc sống dễ dàng hơn: (. Tôi đã có thể làm cho cuộc sống khó khăn hơn cho bản thân mình bằng cách sử dụng virtualenv để giữ cho mọi thứ gọn gàng và ngăn nắp)

(myenv3)[email protected]:~/myenv3$ bin/pip install pyqrencode 
Downloading/unpacking pyqrencode 
    Downloading pyqrencode-0.2.tar.gz 
    Running setup.py egg_info for package pyqrencode 

Installing collected packages: pyqrencode 
    Running setup.py install for pyqrencode 
    building 'qrencode' extension 
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c qrencode.c -o build/temp.linux-i686-2.7/qrencode.o 
    gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions build/temp.linux-i686-2.7/qrencode.o -lqrencode -o build/lib.linux-i686-2.7/qrencode.so 

Successfully installed pyqrencode 
Cleaning up... 

(tôi đoán tôi có lẽ sudo apt-get install libqrencode-dev tại một số điểm trước đó quá.)

Vì vậy, sau đó tôi đã cố gắng để chạy các kịch bản thử nghiệm:

(myenv3)[email protected]:~/myenv3$ python test_qr.py 
Traceback (most recent call last): 
    File "test_qr.py", line 1, in <module> 
    from qrencode import Encoder 
    File "qrencode.pyx", line 1, in init qrencode (qrencode.c:1520) 
ImportError: No module named ImageOps 

:(

Vâng, investigations tiết lộ rằng ImageOps dường như là một phần của PIL ...

(myenv3)[email protected]:~/myenv3$ pip install pil 
Downloading/unpacking pil 
    Downloading PIL-1.1.7.tar.gz (506Kb): 122Kb downloaded 
Operation cancelled by user 
Storing complete log in /home/mat/.pip/pip.log 
(myenv3)[email protected]:~/myenv3$ bin/pip install pil 
Downloading/unpacking pil 
    Downloading PIL-1.1.7.tar.gz (506Kb): 506Kb downloaded 
    Running setup.py egg_info for package pil 
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py 

Installing collected packages: pil 
    Running setup.py install for pil 
    WARNING: '' not a valid package name; please use only.-separated package names in setup.py 
    building '_imaging' extension 
    gcc ... 
    building '_imagingmath' extension 
    gcc ... 
    -------------------------------------------------------------------- 
    PIL 1.1.7 SETUP SUMMARY 
    -------------------------------------------------------------------- 
    version  1.1.7 
    platform  linux2 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
        [GCC 4.5.2] 
    -------------------------------------------------------------------- 
    *** TKINTER support not available 
    *** JPEG support not available 
    *** ZLIB (PNG/ZIP) support not available 
    *** FREETYPE2 support not available 
    *** LITTLECMS support not available 
    -------------------------------------------------------------------- 
    To add a missing option, make sure you have the required 
    library, and set the corresponding ROOT variable in the 
    setup.py script. 

    To check the build, run the selftest.py script. 
    ... 
Successfully installed pil 
Cleaning up... 

Hmm, PIL được cài đặt nhưng chưa nhặt các thư viện tôi cài đặt với sudo apt-get install libjpeg62 libjpeg62-dev libpng12-dev zlib1g zlib1g-dev trước . Tôi không chắc chắn làm thế nào để nói cho pip để nuôi các địa điểm thư viện để setup.py. Googling đề nghị một loạt các ideas mà tôi đã thử, nhưng không ai trong số họ dường như giúp đỡ nhiều hơn là gửi cho tôi vòng trong vòng tròn.

Ubuntu 11.04: Installing PIL into a virtualenv with PIP gợi ý sử dụng gói pillow thay vào đó, vì vậy hãy cố gắng rằng:

(myenv3)[email protected]:~/myenv3$ pip install pillow 
Downloading/unpacking pillow 
    Downloading Pillow-1.7.5.zip (637Kb): 637Kb downloaded 
    Running setup.py egg_info for package pillow 

    ... 
Installing collected packages: pillow 
    Running setup.py install for pillow 
    building '_imaging' extension 
    gcc ... 
    -------------------------------------------------------------------- 
    SETUP SUMMARY (Pillow 1.7.5/PIL 1.1.7) 
    -------------------------------------------------------------------- 
    version  1.7.5 
    platform  linux2 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24) 
        [GCC 4.5.2] 
    -------------------------------------------------------------------- 
    *** TKINTER support not available 
    --- JPEG support available 
    --- ZLIB (PNG/ZIP) support available 
    --- FREETYPE2 support available 
    *** LITTLECMS support not available 
    -------------------------------------------------------------------- 
    To add a missing option, make sure you have the required 
    library, and set the corresponding ROOT variable in the 
    setup.py script. 

    To check the build, run the selftest.py script. 
    ... 
Successfully installed pillow 
Cleaning up... 

Vâng, chúng ta dường như có JPEG và PNG hỗ trợ lần này, yay!

(myenv3)[email protected]:~/myenv3$ python test_qr.py 
Traceback (most recent call last): 
    File "test_qr.py", line 1, in <module> 
    from qrencode import Encoder 
    File "qrencode.pyx", line 1, in init qrencode (qrencode.c:1520) 
ImportError: No module named ImageOps 

Vẫn không có ImageOps. Bây giờ tôi đang bối rối, là ImageOps mất tích từ gối, hoặc nó là một vấn đề khác nhau mà cũng đã có với pil.

+1

apt-get cài đặt python-hình ảnh – jterrace

+0

@jerrace Đã có, nhưng tôi giả định rằng được vô hiệu hóa bởi virtualenv --no-site-packages – Mat

+0

Điều này nghe với tôi như nó có thể được kích hoạt bởi PIL đang cài đặt hai cách - hoặc là trong không gian tên PIL hoặc như các gói riêng lẻ. Có phải 'pyqrencode' sử dụng' import ImageOps' hoặc 'import PIL.ImageOps' không? Hãy thử chuyển đổi nó sau đó xây dựng lại. – agf

Trả lời

12

tôi thấy hai vấn đề riêng biệt ở đây:

  1. theo dõi tất cả các module python bạn cần cho dự án của bạn.

  2. Theo dõi tất cả các thư viện động bạn cần cho các mô đun python trong dự án của bạn.

Đối với vấn đề đầu tiên, tôi nhận thấy rằng buildout là trợ giúp tốt, mặc dù phải mất một lúc để nắm bắt.

Trong trường hợp của bạn, tôi sẽ bắt đầu bằng cách tạo thư mục cho dự án mới của tôi. Sau đó tôi sẽ đi vào thư mục đó và tải bootstrap.py

wget http://python-distribute.org/bootstrap.py 

Sau đó tôi sẽ tạo ra một buildout.cfg file:

[buildout] 
parts = qrproject 
     python 
eggs = pyqrencode 

[qrproject] 
recipe = z3c.recipe.scripts 
eggs = ${buildout:eggs} 
entry-points= qrproject=qrprojectmodule:run 
extra-paths = ${buildout:directory} 

# This is a simple way of creating an interpreter that will have 
# access to all the eggs/modules that this project uses. 
[python] 
recipe = z3c.recipe.scripts 
interpreter = python 
eggs = ${buildout:eggs} 
extra-paths = ${buildout:directory} 

Trong buildout.cfg này Tôi tham chiếu đến mô-đun qrprojectmodule (trong mục nhập dưới [qrproject]. Điều này sẽ tạo bin/qrproject chạy hàm chạy trong mô-đun qrprojectmodule. Vì vậy, tôi cũng sẽ tạo ra các tập tin qrprojectmodule.py

import qrencode 

def run(): 
    print "Entry point for qrproject. Happily imports qrencode module" 

Bây giờ là lúc để chạy bootstrap.py với nhị phân python bạn muốn sử dụng:

python bootstrap.py 

Sau đó chạy ra bin/buildout

bin/buildout 

Điều này sẽ tạo thêm hai tệp nhị phân itional trong thư mục bin/ - bin/qrprojectbin/python. Trước đây là nhị phân chính của dự án của bạn. Nó sẽ được tạo tự động mỗi khi bạn chạy buildout và sẽ có tất cả các mô-đun và trứng bạn muốn tải. Thứ hai chỉ đơn giản là một cách thuận tiện để có được một dấu nhắc python, nơi tất cả các mô-đun và trứng của bạn được nạp, để gỡ lỗi dễ dàng. Điều tốt ở đây là bin/buildout sẽ tự động cài đặt bất kỳ quả trứng trăn nào mà trứng (trong trường hợp pyqrencode của bạn) đã chỉ định là phụ thuộc.

Thực ra, có thể bạn sẽ gặp lỗi biên dịch trong bước bạn chạy bin/buildout. Điều này là do bạn cần giải quyết vấn đề 2: Tất cả các thư viện động có sẵn trên hệ thống của bạn. Trên Linux, tốt nhất là nên nhờ hệ thống đóng gói của bạn giúp đỡ. Tôi sẽ giả sử bạn đang sử dụng một dẫn xuất Debian như Ubuntu ở đây.

Trang web pyqrencode quy định rằng bạn cần thư viện libqrencode để pyqrencode hoạt động. Vì vậy, tôi đã sử dụng trình quản lý gói của mình để tìm kiếm điều đó:

$ apt-cache search libqrencode 
libqrencode-dev - QR Code encoding library -- development 
libqrencode3 - QR Code encoding library 
qrencode - QR Code encoder into PNG image 

Trong trường hợp này, tôi muốn cài đặt thư viện liên kết và tệp tiêu đề cần thiết để biên dịch mô-đun C python. Ngoài ra, hệ thống phụ thuộc trong trình quản lý gói sẽ đảm bảo rằng nếu tôi cài đặt libqrencode-dev, tôi cũng sẽ nhận được libqrencode3, vì đó là bắt buộc khi chạy, tức là sau khi biên dịch mô-đun.

Vì vậy, tôi cài đặt gói:

sudo apt-get install libqrencode-dev 

Một khi đã hoàn tất, chạy lại bin/buildout và các mô-đun pyqrencode sẽ (hy vọng) biên dịch và cài đặt thành công. Bây giờ, hãy thử chạy bin/qrproject

$ bin/qrproject 
Entry point for qrproject. Happily imports qrencode module 

Thành công! :-)

Vì vậy, trong bản tóm tắt:

  1. Sử dụng buildout để tự động tải về và cài đặt tất cả các module python/trứng bạn cần cho dự án của bạn.

  2. Sử dụng trình quản lý gói của hệ thống để cài đặt bất kỳ thư viện động (C) nào do các mô-đun python bạn sử dụng.

Lưu ý rằng trong nhiều trường hợp đã có các phiên bản đóng gói của mô-đun python có sẵn trong hệ thống gói. Ví dụ: pil có sẵn bằng cách cài đặt gói python-hình ảnh trên Ubuntu. Trong trường hợp này, bạn không cần phải cài đặt nó thông qua buildout, và bạn không cần phải lo lắng về các thư viện đang có sẵn - trình quản lý gói sẽ cài đặt tất cả các phụ thuộc cần thiết để module chạy. Tuy nhiên, thực hiện nó thông qua quá trình xây dựng có thể giúp phân phối dự án của bạn dễ dàng hơn và làm cho nó chạy trên các hệ thống khác.

+0

+ một triệu - một câu trả lời tuyệt vời! – katrielalex

0

Câu chuyện của bạn nhắc tôi về những trải nghiệm ban đầu của tôi với Linux và tại sao tôi yêu APT.

Không có giải pháp chung cho vấn đề chung của bạn; điều tốt nhất bạn có thể làm là tận dụng lợi thế của công việc này hoặc của người khác. Các trình đóng gói Debian thực hiện một công việc tuyệt vời là gắn cờ các gói phụ thuộc của các gói, vì vậy apt-get sẽ lấy ra những gì bạn cần. Vì vậy, chiến lược của tôi chỉ đơn giản là tránh xây dựng và cài đặt các công cụ của riêng tôi và sử dụng apt-get ở bất cứ nơi nào có thể.

Lưu ý rằng Ubuntu dựa trên Debian và do đó thu được lợi ích của công việc của các gói Debian. Tôi đã không sử dụng Fedora nhưng tôi nghe nói rằng các gói không được tổ chức tốt như các gói từ Debian.

+0

yes - "apt" rất tốt cho các bản phân phối dựa trên Debian (bao gồm cả Ubuntu). "yum" là tốt như nhau (cho Redhat, Centos và SuSE, trong số những người khác). PS: Mục tiêu chính của bạn vào thời điểm này là khắc phục "apt-get install python-imaging". Bạn đang khá nhiều hơi say cho đến khi bạn nhận được rằng làm việc; bạn nên ở nhà miễn phí sau khi bạn làm cho nó hoạt động. – paulsm4

Các vấn đề liên quan