2015-06-05 16 views
39

Wygląda na to, że istnieje już sporo pytań o względny import w Pythonie 3, ale po przejściu przez wiele z nich wciąż nie znalazłem odpowiedzi na mój problem. , więc tutaj jest pytanie.poza błędem pakietu najwyższego poziomu w względnym imporcie

Mam pakiet przedstawiony poniżej

package/ 
    __init__.py 
    A/ 
     __init__.py 
     foo.py 
    test_A/ 
     __init__.py 
     test.py 

i mam jedną linię w test.py:

from ..A import foo 

teraz jestem w folderze package i biegnę

python -m test_A.test 

Otrzymałem wiadomość

"ValueError: attempted relative import beyond top-level package" 

ale jeśli jestem w katalogu nadrzędnego package, na przykład, biegnę:

cd .. 
python -m package.test_A.test 

wszystko jest w porządku.

teraz moje pytanie brzmi: kiedy jestem w folderze package i uruchomić moduł wewnątrz test_A sub-pakietu jako test_A.test, w oparciu o moje zrozumienie, ..A idzie się tylko jeden poziom, który jest nadal w ramach package folder, dlaczego daje komunikat z informacją: beyond top-level package. Jaki jest dokładnie powód, który powoduje ten komunikat o błędzie?

+0

możliwe duplikat [Jak zrobić względną przywozu w Pythonie?] (Http://stackoverflow.com/questions/72852/how-to- do-relative-import-in-python) – SimKev2

+4

ten wpis nie wyjaśnił mojego błędu "poza pakietem najwyższego poziomu" – shelper

+0

Mam tu pewną myśl, więc kiedy uruchom test_A.test jako moduł, ".." przechodzi powyżej test_A, co jest już najwyższy poziom test_Atest importu, myślę, że poziom pakietu nie jest poziomem katalogu, ale ile poziomów importujesz pakiet. – shelper

Odpowiedz

21

Założenie:
Jeśli jesteś w katalogu package, A i test_A są oddzielne pakiety.

Wniosek:
..A import są dozwolone tylko w ramach pakietu.

Dalsze wskazówki:
dokonującej importu względne dostępny tylko w opakowaniach jest przydatna, jeśli chcesz, aby wymusić, że pakiety mogą być umieszczone na każdej ścieżce znajduje się sys.path.

+12

Czy jestem jedynym, który myśli, że to wariactwo !? Dlaczego na świecie katalog roboczy nie jest uważany za pakiet? – Multihunter

8
import sys 
sys.path.append("..") # Adds higher directory to python modules path. 

Spróbuj tego. Pracowałem dla mnie.

7

Dlaczego to nie działa? To dlatego, że python nie rejestruje miejsca, z którego został załadowany pakiet. Więc kiedy robisz python -m test_A.test, w zasadzie po prostu odrzuca wiedzę, że jest rzeczywiście przechowywany w package (tj. package nie jest uważany za pakiet). Próba uzyskania dostępu do informacji, której już nie ma (próba utworzenia katalogu siostrzanego w załadowanej lokalizacji) próbuje uzyskać from ..A import foo. Jest to koncepcyjnie podobne do zezwalania na from ..os import path w pliku w math. To byłoby złe, ponieważ chcesz, aby pakiety były odrębne. Jeśli muszą używać czegoś z innej paczki, powinni odnosić się do nich globalnie za pomocą from os import path i pozwolić pythonowi wykombinować, gdzie to jest z $PATH i $PYTHONPATH.

Podczas korzystania z python -m package.test_A.test, używanie from ..A import foo rozwiązuje się dobrze, ponieważ śledzone jest to, co jest w package i właśnie uzyskujesz dostęp do katalogu podrzędnego załadowanej lokalizacji.

Dlaczego Python nie uważa bieżącego katalogu roboczego za pakiet?BRAK CLUE, ale byłby przydatny.

-1

from package.A import foo

myślę, że to wyraźniej niż

import sys 
sys.path.append("..") 
Powiązane problemy