2012-07-30 11 views
17

Wyobraź strukturę katalogów:Czy domyślnie import nie powinien być bezwzględny w python27?

 
/
    a/ 
     __init__.py 
     b.py 
     c.py 
    c.py 

Plik /a/b.py wygląda:

 
import c 
should_be_absolute = c 

wszystkich innych plików (w tym __init__) są puste.

Po uruchomieniu skryptu testowego (przy użyciu Pythona 2.7):

import a.b 
print a.b.should_be_absolute 

z PYTHONPATH=/ z pustym katalogu (tak nic nie dodaje do PYTHONPATH z bieżącego katalogu) pojawia

<module 'a.c' from '/a/c.py'> 

gdzie według do PEP 328 i oświadczenie import <> is always absolute Spodziewam się:

<module 'c' from '/c.py'> 

Dane wyjściowe są zgodne z oczekiwaniami po usunięciu pliku /a/c.py.

Czego mi brakuje? A jeśli to jest prawidłowe zachowanie - jak zaimportować moduł c z b (zamiast a.c)?

Aktualizacja:

Według python dev mailing list wydaje się być błąd w dokumentacji. Import domyślnie jest nie w python27.

+0

Jaka jest twoja kompletna pythonpath? Czy to tylko /? Powinieneś prawdopodobnie używać nazwy pakietu root – jdi

+3

FWIW, działa to tak, jak oczekujesz w Pythonie 3. – geoffspear

+0

@jdi - tak root jest jedyną rzeczą w PYTHONPATH (edytowałem oryginalny post, aby było bardziej jednoznaczne) – karolx

Odpowiedz

26

trzeba dodać from __future__ import absolute_import lub użyj importlib.import_module('c') na Pythonie 2.7

Jest to domyślny na Python 3.

W języku Python wystąpił błąd: __future__.py and its documentation claim absolute imports became mandatory in 2.7, but they didn't.

+2

Masz rację! Po dalszym kopaniu znalazłem link do [listy dyskusyjnej python-dev] (http://python.6.n6.nabble.com/status-of-absolute-import-w-python-2-7-td1850742.html) potwierdzające, że funkcja absolute_import nie jest domyślnie włączona w python27. – karolx

+0

rodzaj niedorzecznego ... –

0

Jeśli dodajesz tylko / do swojej PYTHONPATH, kolejność wyszukiwania może wciąż szukać c w bieżącym katalogu. Byłoby o wiele lepiej, jeśli umieścić wszystko w ramach pakietu głównego, a skierowane do niej absolutnie:

/myPackage 
    a/ 
     __init__.py 
     b.py 
     c.py 
    __init__.py 
    c.py 

I PYTHONPATH jak: export PYTHONPATH=/:$PYTHONPATH

Więc w swojej a.c byś zrobił, a spośród nich:

from myPackage import c 
from myPackage.c import Foo 
import myPackage.c 

ten sposób, to zawsze w stosunku do pakietu.

+0

Dzięki, ale Pytanie brzmi raczej, czy jest to prawidłowe zachowanie, a nie jak zreorganizować kod, aby działało. Rzeczywistym problemem, który rozwiązuję, jest to, że "c" jest nazwą modułu wbudowanego Pythona, a kod w paczce, którą teraz pracuję, przesyła go w cień (a według dokumentów Pythona nie powinien) – karolx

-1

"Absolutny" nie oznacza tego, który według ciebie jest; zamiast tego oznacza to, że odbywa się "zwykła" procedura rozstrzygania pakietów: najpierw znajduje się w katalogu pakietu, a następnie we wszystkich elementach sys.path; który zawiera elementy z PYTHONPATH.

Jeśli chcesz, aby naprawdę, możesz użyć narzędzi, takich jak moduł imp, ale polecam od tego coś takiego. Ponieważ generalnie nie powinieneś nigdy tworzyć modułu o takiej samej nazwie jak w standardowej dystrybucji Pythona.

+0

Dzięki @Ivo ale [PEP 328 # rationale-for-absolute-imports] (http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports) stwierdza, że ​​bezwzględny import będzie zawsze moduł lub pakiet dostępny z sys.path_. W pierwszym katalogu nie ma nic o wyszukiwaniu. Czy możesz wskazać na jakiś zasób dokumentujący zachowanie opisane przez Ciebie? – karolx

+0

http://docs.python.org/reference/simple_stmts.html#import jest bardzo jasny na temat procesu, ponieważ jest zaimplementowany: "Jeśli importowany moduł ma być zawarty w pakiecie, to drugi argument przekazany do find_module(), __path__ na pakiecie macierzystym, jest używane jako źródło ścieżek. " – Ivo

+0

"najpierw znajduje się w katalogu paczki". Nie, to względny import. –

Powiązane problemy