2013-11-27 12 views
9

Tôi có một thư mục với một gói python như sau:Sphinx và tương nhập khẩu bằng Python 3. *

--docs/index.rst 
--docs/... 
--app/__init__.py 
--app/foo.py 

và tôi đang sử dụng Sphinx với autodocs cung cấp tư liệu ứng dụng (trong python 3.3).

Bây giờ, trong conf.py (bên docs/), tôi có

sys.path.insert(0, os.path.abspath('../app')) 

tôi cd vào docs/, chạy

make html 

mà mang lại cho tôi

SystemError: mô-đun Chánh '' không đã tải, không thể thực hiện nhập tương đối

cho tất cả các module có một

from .foo import Bar 

Tôi có một cài đặt virtualenv sạch của Sphinx sử dụng

pip install Sphinx 

sau khi tôi tạo ra môi trường (sạch) cho python 3.3.

Tôi đang thiếu gì?

Tôi đã di chuyển dự án từ python 2. * sang python 3. * khi điều này xảy ra. Tất cả các dự án đang làm việc, nhưng điều này ...

+0

Có phải 'ứng dụng' là một gói cấp cao nhất hay thư mục mà các gói cấp cao nhất của bạn ở trong đó không? – abarnert

+0

Tôi không chắc tôi đã hiểu câu hỏi của bạn @abarnert. 'app' không có thư mục bên trong, chỉ là một tập hợp' * .py', bao gồm '__init __. py'. sphinx chỉ tài liệu app dir. –

+0

Nếu 'ứng dụng' có' __init __. Py' bên trong, thì đó là một gói. Và đó là vấn đề của bạn. Hãy để tôi viết một câu trả lời để giải thích. – abarnert

Trả lời

14

Thư mục app của bạn là một gói. Một gói là một thư mục với __init.py__ và các tệp khác bên trong nó.

Nếu bạn đặt thư mục gói trên số sys.path, mọi thứ sẽ bị sai.

Hãy lấy một ví dụ:

root/ 
    app/ 
     app/__init__.py 
     app/spam.py 
     app/eggs.py 

Nếu bạn có root trên sys.path của bạn (vì đó là thư mục làm việc hiện tại của bạn, hoặc bởi vì bạn làm điều đó một cách rõ ràng, hoặc bởi vì bạn đã cài đặt mọi thứ một cách chính xác để của bạn site-packages), sau đó app là một gói, app.spam là một mô-đun và trong vòng app.eggs, .spam là mô-đun đó. Vì vậy, tất cả mọi thứ hoạt động.

Nếu bạn có app trên sys.path của bạn, sau đó app không phải là một gói, spam là một mô-đun, và, trong vòng eggs, .spam không phải là bất cứ điều gì. Vì vậy, bạn không thể sử dụng nhập khẩu tương đối.

Nếu bạn có cả trên sys.path của bạn, sau đó app là một gói, spamapp.spam đều module khác nhau (với những nội dung tương tự, thực hiện hai lần), và trong vòng app.eggs, .spam là một mô-đun, nhưng trong vòng eggs, .spam không phải là bất cứ điều gì. Điều này sẽ khiến bạn không có vấn đề gì.


Vì vậy, nhiều khả năng, việc sửa chữa mà bạn muốn là thế này:

sys.path.insert(0, os.path.abspath('..')) 

Nếu có gói khác, hoặc thư mục đầy đủ các mã Python mà không phải là bao bì, trong .. mà bạn don' Nếu bạn muốn tự động sửa đổi (ví dụ: một thư mục tests với tests/test_spam.py), thì bạn cần phải cấu trúc lại các thư mục của mình để đặt app vào một số thư mục không có bất kỳ mã Python nào khác, như sau:

root/ 
    src/ 
     app/ 
    tests/ 
    doc/ 

Ngoài ra, nếu bạn không muốn app được một gói, mà đúng hơn là một thư mục gốc sys.path, sau đó giết __init__.py, và để lại app trực tiếp trong sys.path. Nhưng trong trường hợp đó, bạn không thể sử dụng nhập khẩu tương đối trong gói; tất cả các mô-đun trong app là các mô-đun cấp cao nhất và phải được nhập như vậy.


Các Packages phần của hướng dẫn (và phần còn lại của chương ở trên nó) giải thích một số điều này, nhưng có tài liệu giới thiệu có lẽ tốt hơn ra khỏi đó.

Để biết chi tiết đầy đủ, trong 3.3+, The import system có mọi thứ, được sắp xếp hợp lý; đối với các phiên bản cũ hơn, tài liệu tham chiếu bị lầy lội, không đầy đủ và phân tán; bạn phải bắt đầu tại The import statement, và sau đó đọc The Knights Who Say Neeeow ... Wum ... Ping! (về cơ bản là PEP nhưng 1.5 chưa có PEP) và thậm chí có thể là tài liệu ni, nếu bạn có thể tìm thấy nó, cộng với các PEP khác nhau và các mục nhật ký thay đổi nhỏ giải thích mọi thứ đã thay đổi như thế nào giữa 1,5 và 2,7 hoặc 3,2 hoặc bất kỳ thứ gì.

+0

Câu trả lời rất hay. Cảm ơn bạn. Bạn đã làm cho tôi nhận ra tôi có rất nhiều điều để tìm hiểu về hệ thống mới. –

+2

@ J.C.Leitão: Nếu bạn đang làm điều tương tự trong Python 2.x, nó cũng sai ở đó. Nó chỉ là 2,7 cho phép bạn nhận được đi với các công cụ văn bản đó là một nửa giữa Python 1,5 phong cách và Python-3.3 phong cách và đôi khi nó hoạt động ... – abarnert

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