Używam Python 3.5.1. Przeczytałem tutaj dokument i pakiet: https://docs.python.org/3/tutorial/modules.html#packages
Teraz mam następującą strukturę:
/home/wujek/Playground/a/b/module.py
module.py
:
class Foo:
def __init__(self):
print('initializing Foo')
Teraz, będąc w /home/wujek/Playground
:
~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>
Podobnie, teraz w domu, superfolder Playground
:
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>
Właściwie mogę robić różne rzeczy:
~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b
Dlaczego to działa? I choć nie musiał być __init__.py
pliki (pustych będzie działać) w obu a
i b
dla module.py
aby być importable gdy pytona punkty ścieżka do Playground
folderu?
Wygląda na to, że zmieniło się to z Python 2.7:
~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module
Z __init__.py
obu ~/Playground/a
i ~/Playground/a/b
działa dobrze.
źródło
Zen Of Python
Explicit is better than implicit.
__init__.py
, a czasem nie. Kiedy potrzebuję tych rzeczy w Pythonie 3, tworzę nowy__init__.py
ze specyficznym kodem, inaczej nie. Przydaje się to, aby wizualnie wiedzieć, które pakiety mają niestandardowe init. Zamiast tego w Pythonie 2 zawsze muszę umieścić__init__.py
(często pusty), co sprawia, że jest ich ogromna liczba, a na koniec trudniej zapamiętać, gdzie umieściłeś swój kod init. Powinno to również pasować „Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego”.WAŻNY
@ Odpowiedź Mike'a jest poprawna, ale zbyt nieprecyzyjna. Prawdą jest, że Python 3.3+ obsługuje pakiety Implicit Namespace, które pozwalają mu tworzyć pakiet bez
__init__.py
pliku.Dotyczy to TYLKO plików EMPTY
__init__.py
. Więc EMPTY__init__.py
pliki nie są już potrzebne i można je pominąć. Jeśli chcesz uruchomić określony skrypt inicjujący podczas importowania pakietu lub dowolnego z jego modułów lub podpakietów, nadal potrzebujesz__init__.py
pliku. Jest to świetna odpowiedź na pytanie o przepełnienie stosu, dlaczego chcesz użyć__init__.py
pliku do przeprowadzenia dalszej inicjalizacji w przypadku, gdy zastanawiasz się, dlaczego jest to w ogóle przydatne.Przykład struktury katalogów:
parent_package/child_package/__init__.py
:PRZYKŁADY
Poniższe przykłady pokazują, w jaki sposób skrypt inicjujący jest wykonywany podczas
child_package
importowania jednego lub jednego z jego modułów.Przykład 1 :
Przykład 2 :
źródło
run_script.py
sam katalog, coparent_package
mogę importować jakfrom parent_package.child_package import child1
bez__init__.py
?child1.py
,child2.py
zamiast po prostu składać ich kod__init__
bezpośrednio w .py.__init__
być importami względnymi, tj.from . import child1
? Absolutny import daje miModuleNotFoundError
(w Pythonie 3.6)__init__.py
jest czasem potrzebny, na przykład gdy chcesz odwołać się do podfolderu jako pakietu. Na przykład, jeśli uruchomiępython -m test.foo
, nie zadziała, dopóki nie utworzę pustego__init__.py
folderu testowego. Mówię tutaj o wersji 3.6.6!Jeśli masz
setup.py
swój projekt i korzystasz zfind_packages()
niego, konieczne jest posiadanie__init__.py
pliku w każdym katalogu, aby pakiety mogły zostać automatycznie znalezione.UPD : Jeśli chcesz korzystać z niejawnych pakietów przestrzeni nazw,
__init__.py
musisz po prostu użyćfind_namespace_packages()
zamiast tegoDokumenty
źródło
Powiedziałbym, że należy pominąć
__init__.py
tylko wtedy, gdy ktoś chce mieć pakiet niejawnej przestrzeni nazw . Jeśli nie wiesz, co to znaczy, prawdopodobnie nie chcesz tego i dlatego powinieneś nadal używać__init__.py
parzystości w Pythonie 3.źródło