2013-11-27 19 views
9

Mam katalog z pakietu python następująco:Sphinx i względne import w Pythonie 3. *

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

i używam Sfinks z autodocs dokumentowania aplikację (w Pythonie 3.3).

Teraz w conf.py (wewnątrz docs/), mam

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

I cd do docs/ uruchom

make html 

który daje mi

SystemError: Moduł rodzica "nie załadowany, nie można wykonać względnego importu

do wszystkich modułów, które mają

from .foo import Bar 

mam czysty montaż virtualenv Sphinx używając

pip install Sphinx 

po stworzyłem (Clean) środowisko dla Pythona 3.3.

Czego mi brakuje?

Przenosiłem projekt z Pythona 2. * do Pythona 3. * kiedy to się stało. Cały projekt działa, ale ten ...

+0

Czy 'app' jest pakietem najwyższego poziomu lub katalogiem, w którym znajdują się pakiety najwyższego poziomu? – abarnert

+0

Nie jestem pewien, czy zrozumiałem twoje pytanie @abarnert. 'app' nie ma wewnątrz katalogu, tylko zbiór' * .py', w tym '__init __. py'. sfinks dokumentuje tylko aplikację reż. –

+0

Jeśli 'app' ma' __init __. Py' wewnątrz, to jest to pakiet. I to jest twój problem. Pozwól mi napisać odpowiedź na wyjaśnienia. – abarnert

Odpowiedz

14

Twój katalog app jest pakietem. Pakiet to katalog z __init.py__ i innymi plikami w nim.

Jeśli umieścisz katalog paczek na swoim sys.path, wszystkie rodzaje rzeczy pójdą źle.

Weźmy przykład:

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

Jeśli masz root na sys.path (bo to twój bieżący katalog roboczy, lub dlatego, że robisz to jawnie, albo dlatego, że masz zainstalowane prawidłowo do rzeczy Twój site-packages), a następnie app jest pakietem, app.spam jest modułem, a w ramach app.eggs, .spam jest tym modułem. Wszystko działa.

Jeśli masz app na swojej sys.path, następnie app nie jest pakietem, spam jest modułem, a wewnątrz eggs, .spam nie ma nic. Nie możesz więc używać względnego importu.

Jeśli masz zarówno na swoim sys.path, następnie app to pakiet, spam i app.spam są zarówno różne moduły (o tej samej treści, wykonywane dwa razy), aw ciągu app.eggs, .spam jest modułem, ale w eggs, .spam nie jest niczym. To nie spowoduje końca problemów.


Tak, najprawdopodobniej, fix chcesz to:

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

Jeśli istnieją inne pakiety, lub katalogi pełne kodu Pythona, które nie są pakiety, w .. że don” t chcą AutoDoc (np tests katalog z tests/test_spam.py), a następnie trzeba będzie zrestrukturyzować swoje katalogi umieścić app do jakiegoś katalogu, który nie ma żadnego innego kodu Pythona w nim tak:

root/ 
    src/ 
     app/ 
    tests/ 
    doc/ 

Ewentualnie, jeśli nie chcą app być pakiet, ale raczej jako katalog główny sys.path, a następnie zabić __init__.py i pozostawić app bezpośrednio w sys.path. Ale w takim przypadku nie można używać importu względnego wewnątrz pakietu; wszystkie moduły w app są modułami najwyższego poziomu i muszą zostać zaimportowane jako takie.


Sekcja Packages z samouczka (i reszta rozdziału nad nim) wyjaśnia niektóre, ale nie ma chyba lepsza dokumentacja wprowadzające tam.

Aby uzyskać szczegółowe informacje, w wersji 3.3+, The import system ma wszystko, ładnie zorganizowany; w przypadku starszych wersji dokumenty referencyjne są mętne, niekompletne i rozproszone; musisz zacząć od The import statement, a następnie przeczytać The Knights Who Say Neeeow ... Wum ... Ping! (która jest w zasadzie PEP, ale 1.5 nie miała jeszcze PEP) i ewentualnie nawet dokumentację ni, jeśli możesz ją znaleźć, plus różne PEP i małe wpisy dziennika zmian, które wyjaśniają jak zmieniło się między 1,5 a 2,7 lub 3,2 lub cokolwiek innego.

+0

Bardzo dobra odpowiedź. Dziękuję Ci. Uświadomiłeś mi, że muszę się dużo nauczyć o nowym systemie. –

+2

@ J.C.Leitão: Jeśli robiłeś to samo w Pythonie 2.x, to również tam było źle. Po prostu 2.7 pozwala uciec od pisania rzeczy w połowie drogi między stylem Python 1.5 a stylem Python-3.3, a czasami działa ... – abarnert

Powiązane problemy