2013-01-08 20 views
13

Mam pakiet p, który ma moduły a i b. a polega na b:Moduł importu siły z bieżącego katalogu

b.py treść:

import a 

Jednak chcę zapewnić że b importuje mój moduł a z tego samego katalogu p pakietu, a nie tylko dowolny moduł a z PYTHONPATH.

Więc próbuję zmienić b.py jak następuje:

from . import a 

Działa to tak długo, jak importować b kiedy jestem poza p katalogu pakietu. Biorąc pod uwagę następujące pliki:

/tmp 
    /p 
     a.py 
     b.py 
     __init__.py 

następujące prace:

$ cd /tmp 
$ echo 'import p.b' | python 

Następujące nie działa:

$ cd /tmp/p 
$ echo 'import b' | python 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "b.py", line 1, in <module> 
    from . import a 
ValueError: Attempted relative import in non-package 

Dlaczego?

P.S. Używam Python 2.7.3

Odpowiedz

5

Po rereading Python import documentation, prawidłowa odpowiedź do mojego pierwotnego problemu jest:

Aby zapewnić b import a z własnym pakietem Jej wystarczy napisać następujących w b:

import a 

Oto cytat z docs:

The submodules often need to refer to each other. For example, the surround module might use the echo module. In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path.

Uwaga: As J. F. Sebastian sugeruje w komentarzu poniżej, korzystanie z importu ukrytych nie jest zalecane, a są one w rzeczywistości, poszedł w Pythonie 3.

+9

nie stosuj niejawnych względnych importów (nie ma ich w Pythonie 3). Zawsze używaj bezwzględnego importu ('from p import a' (dodaj' from __future__ import absolute_import' przed nim, jeśli istnieje plik 'p/p.py')) lub jawnego względnego importu (' od. Import a' (jeśli nie jest moduł '__main__')). Nie uruchamiaj skryptów z katalogu paczek w Pythonie; to przedkłada ten katalog do sys.path, co może prowadzić do tego, że ten sam moduł jest dostępny pod różnymi nazwami, co prowadzi do błędów związanych ze stanem modułu (jeśli stosujesz niejawny import względny, a także cienie w tym przypadku inne moduły tweenvel). – jfs

+0

Dobre notatki. Dzięki! –

+1

Jeśli ponownie prześlesz odpowiedź jako odpowiedź, zaakceptuję ją. –

0

Ponieważ istnieje plik __init__.py w /p. Ten plik mówi Pythonowi: "Wszystkie moduły w tym folderze znajdują się w pakiecie p".

Dopóki istnieje plik __init__.py, można zaimportować b jako p.b, bez względu na to, gdzie jesteś.

więc prawidłowa import w b.py byłoby: import p.a

+0

Która wersja Pythona? To zachowanie zmieniło się w przeszłości. –

+0

Zmiana "b.py" zgodnie z sugestią. Teraz uruchomienie 'import b' daje' ImportError: Brak modułu o nazwie p.a'. Python 2.7.3 –

+0

Nigdy nie powinieneś używać 'import b' w takim scenariuszu. Zawsze używaj 'import p.b' lub udostępniaj niezbędne symbole z' __init __. Py' oraz 'import p', aby ukryć wewnętrzne szczegóły. –

0

import Względne pracować tylko w pakietach.

Jeśli importujesz b z miejsca, w którym się znajdujesz, nie ma pojęcia o paczce, a zatem nie ma możliwości względnego importu.

Jeśli importujesz p.b, jest to moduł b w pakiecie c.

Nie ma znaczenia struktura katalogów, ale struktura pakietów.

Powiązane problemy