Mój pakiet ma następującą strukturę:
mobilescouter/
__init__.py #1
mapper/
__init__.py #2
lxml/
__init__.py #3
vehiclemapper.py
vehiclefeaturemapper.py
vehiclefeaturesetmapper.py
...
basemapper.py
vehicle/
__init__.py #4
vehicle.py
vehiclefeature.py
vehiclefeaturemapper.py
...
Nie jestem pewien, jak __init__.py
pliki powinny być poprawnie zapisane.
Do __init__.py #1
wygląda następująco:
__all__ = ['mapper', 'vehicle']
import mapper
import vehicle
Ale jak na przykład powinien __init__.py #2
wyglądać? Mój jest:
__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml
Kiedy należy __all__
stosować?
Odpowiedzi:
__all__
jest bardzo dobry - pomaga poprowadzić instrukcje importowania bez automatycznego importowania modułów http://docs.python.org/tutorial/modules.html#importing-from-a-packageużyciu
__all__
iimport *
jest zbędny, tylko__all__
jest potrzebnaMyślę, że jednym z najpotężniejszych powodów do użycia
import *
w__init__.py
celu importowania pakietów jest możliwość refaktoryzacji skryptu, który rozrósł się do wielu skryptów bez zrywania istniejącej aplikacji. Ale jeśli projektujesz pakiet od samego początku. Myślę, że najlepiej zostawić__init__.py
pliki puste.na przykład:
wtedy aplikacja rośnie, a teraz jest to cały folder
wtedy skrypt init może powiedzieć
aby skrypt napisany w celu wykonania następujących czynności nie ulegał awarii podczas zmiany:
źródło
__all__
iimport *
jest redundantny”,__all__
jest używany przez konsumenta modułu ifrom foo import *
jest używany przez sam moduł do korzystania z innych ....using __all__ and import * is redundant, only __all__ is needed
Jak się mają zbędne? Robią różne rzeczy.Moje własne
__init__.py
pliki są puste częściej niż nie. W szczególności nigdy nie mam tegofrom blah import *
jako część__init__.py
- jeśli „importowanie pakietu” oznacza uzyskanie wszelkiego rodzaju klas, funkcji itp. Zdefiniowanych bezpośrednio jako część pakietu, to zamiast tego skopiowałbym leksykalnie zawartośćblah.py
pakietu__init__.py
i usunąłblah.py
( zwielokrotnienie plików źródłowych tutaj nie ma znaczenia).Jeśli nalegasz na wspieranie
import *
idiomów (eek), to użycie__all__
(z tak niewielką listą imion, jak tylko możesz się w nich znaleźć) może pomóc w kontrolowaniu szkód. Ogólnie rzecz biorąc, przestrzenie nazw i jawne importowanie to dobre rzeczy i zdecydowanie sugeruję ponowne rozważenie każdego podejścia opartego na systematycznym pomijaniu jednego lub obu pojęć! -)źródło
import *
, musisz bezwarunkowo zaakceptować wszystkie frameworki, nawet te, których nigdy nie będziesz używać. pozostawienie__init__.py
pustego daje więcej szans niż tylko semantyczne „wszystko albo nic”. pomyśl o pokręconym.from mobilescouter import A, B
jest tylko wierszem kodu i nie masz projektu z 666 klasami, a każdy z własnym plikiem, prawda? jeśli masz dwa lub więcejimport *
w kodzie, wypełniasz przestrzeń nazw potencjalnymi śmieciami i szybko zapomnisz, skądA
pochodzą. A jeśli to samo zrobi górna paczka? chwytasz wszystkie sub-paczki i sub-paczki. jak mówi zen Pythona, jawne jest lepsze niż niejawne.Twój
__init__.py
powinien mieć docstring .Mimo że cała funkcjonalność jest zaimplementowana w modułach i podpakietach, dokumentowanie pakietu jest miejscem, w którym można rozpocząć dokumentowanie. Rozważmy na przykład pakiet python
email
. Dokumentacja pakietu jest wstępem opisującym cel, tło oraz sposób współpracy różnych komponentów w pakiecie. Jeśli automatycznie generujesz dokumentację z dokumentów w postaci sfinksa lub innego pakietu, dokumentacja pakietu jest właściwym miejscem do opisania takiego wprowadzenia.W przypadku innych treści zobacz doskonałe odpowiedzi firecrow i Alex Martelli .
źródło
__init__.py
oemail
pakiecie są zgodne z tymi wytycznymi? Widzę dokumentację w jednym wierszu, która nie robi wiele, aby wyjaśnić „jak różne komponenty w pakiecie działają razem”.