Zastanawiam się nad preferowanym sposobem importowania pakietów w aplikacji Python. Mam taką strukturę pakietu:
project.app1.models
project.app1.views
project.app2.models
project.app1.views
import project.app1.models
i project.app2.models
. Przychodzą mi na myśl dwa sposoby, aby to zrobić.
W przypadku importu bezwzględnego:
import A.A
import A.B.B
lub z wyraźnym importem względnym, jak wprowadzono w Pythonie 2.5 z PEP 328 :
# explicit relative
from .. import A
from . import B
Jaki jest najbardziej pythonowy sposób na zrobienie tego?
python
package
python-import
Daniel Hepper
źródło
źródło
from _ import ...
, dzięki czemu byłyby przykładyfrom .. import A
ifrom . import B
import ..A
nafrom .. import A
. Niezwykłe, że minęło tylko 9 lat, zanim ktoś zauważył;)Odpowiedzi:
Absolutny import. Od PEP 8:
Jawne importy względne to fajna funkcja języka (chyba), ale nie są tak wyraźne, jak import absolutny. Bardziej czytelna forma to:
import A.A import A.B.B
zwłaszcza jeśli importujesz kilka różnych przestrzeni nazw. Jeśli spojrzysz na dobrze napisane projekty / samouczki, które zawierają import z pakietów, zwykle są one zgodne z tym stylem.
Kilka dodatkowych naciśnięć klawiszy, które przyjmujesz, aby były bardziej wyraźne, pozwoli zaoszczędzić innym (i być może Tobie) dużo czasu w przyszłości, gdy będą próbowali rozgryźć twoją przestrzeń nazw (zwłaszcza jeśli dokonasz migracji do 3.x, w której część pakietu nazwy uległy zmianie).
źródło
Względne importowanie w Pythonie nie jest już zdecydowanie odradzane, ale w takim przypadku zdecydowanie zaleca się użycie bezwzględnego importu.
Zobacz tę dyskusję, cytując samego Guido:
OP poprawnie łączy PEP 328, który mówi:
Zobacz także prawie zduplikowane pytanie Kiedy i dlaczego używać importu względnego w Pythonie
Oczywiście nadal pozostaje kwestią gustu. Chociaż łatwiej jest przenosić kod za pomocą względnych importów, może to również nieoczekiwanie zepsuć wszystko; a zmiana nazwy importu nie jest taka trudna.
Aby wymusić nowe zachowanie z PEP 328, użyj:
from __future__ import absolute_import
W takim przypadku niejawny import względny nie będzie już możliwy (np.
import localfile
Nie będzie już działać, tylkofrom . import localfile
). Aby zachować czyste i odporne na przyszłość zachowanie, zaleca się korzystanie z bezwzględnego importu.Ważnym zastrzeżeniem jest to, że ze względu na PEP 338 i PEP 366 , import względny wymaga, aby plik Pythona został zaimportowany jako moduł - nie można wykonać pliku file.py, który ma import względny, w przeciwnym razie otrzymasz plik
ValueError: Attempted relative import in non-package
.To ograniczenie należy wziąć pod uwagę przy ocenie najlepszego podejścia. Guido jest przeciwny uruchamianiu skryptów z modułu w każdym przypadku:
Wyczerpujące dyskusje na ten temat można znaleźć na SO; re. Python 3 to dość obszerne:
źródło
import .baz
- to tylko jedna uproszczona z wielu podobnych sytuacji opisanych w PEP.Importy względne nie tylko pozostawiają swobodę późniejszej zmiany nazwy pakietu bez zmiany dziesiątek wewnętrznych importów, ale także udało mi się rozwiązać pewne problemy związane z takimi rzeczami, jak import cykliczny lub pakiety przestrzeni nazw, ponieważ nie wysyłają one Pythona z powrotem do top ”, aby ponownie rozpocząć wyszukiwanie następnego modułu z przestrzeni nazw najwyższego poziomu.
źródło
python setup.py install
lubpython setup.py develop
z jakiegokolwiek powodu), w takich przypadkach rozwidlam kod źródłowy i dodaję go jako podmoduł git. Gdy te pakiety używają importu bezwzględnego dla własnej nazwy pakietu, ich importowanie kończy się niepowodzeniem. Jedynym rozwiązaniem jest użycie jawnego importu względnego. Myślę, że to powinno być zachęcane.