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, spam
và app.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ì.
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
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. –
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