2009-12-24 31 views
8

Zasadniczo mam podpakiet o tej samej nazwie, co standardowy pakiet bibliotek ("logowanie") i chciałbym, aby był on w stanie bezwzględnie zaimportować standardową nie ma ważne jak go uruchomić, ale to nie powiedzie się, gdy jestem w pakiecie nadrzędnym.Błąd bezwzględnego importu w podpakiecie, który cienia nazwę pakietu stdlib

To naprawdę wygląda albo błąd, albo nieudokumentowane zachowanie nowego wsparcia "bezwzględnego importu" (nowe od Pythona 2.5). Próbowałem z 2.5 i 2.6.

układ Opakowanie:

foo/ 
    __init__.py 
    logging/ 
     __init__.py 

W foo/__init__.py sprowadzamy nasze własne rejestrowania podpakiet:

from __future__ import absolute_import 
from . import logging as rel_logging 
print 'top, relative:', rel_logging 

W foo/logging/__init__.py chcemy zaimportować pakiet stdlib logging:

from __future__ import absolute_import 
print 'sub, name:', __name__ 

import logging as abs_logging 
print 'sub, absolute:', abs_logging 

Note : Folder zawierający foo znajduje się w sys.path.


Gdy importowane z zewnątrz/powyżej foo wyjście jest, jak oczekiwano

c:\> python -c "import foo" 
sub, name: foo.logging 
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'foo\logging\__init__.pyc'> 

Zatem bezwzględna importu w podpakiecie znajduje pakiet stdlib to pożądane.

Ale kiedy jesteśmy w folderze foo, to zachowuje się inaczej:

c:\foo>\python25\python -c "import foo" 
sub, name: foo.logging 
sub, name: logging 
sub, absolute: <module 'logging' from 'logging\__init__.pyc'> 
sub, absolute: <module 'logging' from 'logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'> 

Podwójne wyjście dla „sub, nazwa” pokazuje, że moja własna Podpakiet zwany „rejestrowanie” importuje sobie po raz drugi, i nie znajduje pakietu stdlib "logging" , mimo że "absolute_import" jest włączony.

Przypadek użycia jest taki, że chciałbym móc pracować z tym pakietem, testować itp., Niezależnie od tego, jaki jest katalog bieżący. Zmiana nazwy z "rejestrowania" na coś innego byłaby obejściem, ale nie jest pożądana, a w każdym razie takie zachowanie nie wydaje się pasować do opisu, jak bezwzględny import powinien działać.

Wszelkie pomysły na temat tego, co się dzieje, czy jest to błąd (mój lub Pythona), czy to zachowanie jest w rzeczywistości implikowane przez jakąś dokumentację?

Edytuj: Odpowiedź gahooa pokazuje wyraźnie, na czym polega problem. Surowy obejście, które dowodzi, że to jest to pokazane tutaj:

c:\foo>python -c "import sys; del sys.path[0]; import foo" 
sub, name: foo.logging 
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'> 

Odpowiedz

10

sys.path[0] jest domyślnie '', co oznacza „bieżący katalog”. Więc jeśli siedzisz w katalogu z logging w nim, to zostanie wybrany jako pierwszy.

Wpadłem na to ostatnio, dopóki nie zdałem sobie sprawy, że faktycznie siedzę w tym katalogu i że sys.path zbierało mój bieżący katalog FIRST, zanim zajrzałem do standardowej biblioteki.

+0

Dzięki. Właśnie zdałem sobie sprawę z tego samego, co rozważałem podczas obiadu.Sądzę, że to nieuniknione, że tak się stanie, chyba że celowo usuniesz sys.path [0] lub przeniesiesz "" do końca lub coś podobnego. Zaznaczę to w moim pytaniu. –

Powiązane problemy