Ich benutze Python 3.5.1. Ich habe das Dokument und den Paketabschnitt hier gelesen: https://docs.python.org/3/tutorial/modules.html#packages
Jetzt habe ich folgende Struktur:
/home/wujek/Playground/a/b/module.py
module.py
::
class Foo:
def __init__(self):
print('initializing Foo')
Jetzt, während in /home/wujek/Playground
:
~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>
In ähnlicher Weise, jetzt zu Hause, Superordner von Playground
:
~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>
Eigentlich kann ich alles Mögliche machen:
~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b
Warum funktioniert das? Ich obwohl es erforderlich sein , __init__.py
Dateien in beide (leeren funktionieren würde) a
und b
für module.py
importierbar zu sein , wenn die Python - Pfad verweist auf den Playground
Ordner?
Dies scheint sich gegenüber Python 2.7 geändert zu haben:
~ $ 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
Mit __init__.py
in beiden ~/Playground/a
und ~/Playground/a/b
es funktioniert gut.
quelle
Zen Of Python
Zeile 2 trotzt :Explicit is better than implicit.
....__init__.py
, manchmal nicht. Wenn ich in Python 3 diese Dinge brauche, erstelle ich einen neuen__init__.py
mit spezifischem Code, sonst nicht. Dies ist praktisch, um visuell zu wissen, welche Pakete eine benutzerdefinierte Init haben. Stattdessen muss ich in Python 2 immer ein__init__.py
(oft leeres) platzieren, wodurch eine große Anzahl von ihnen erstellt wird und es schließlich schwieriger wird, sich daran zu erinnern, wo Sie Ihren Init-Code platziert haben. Dies sollte auch passen "Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun."WICHTIG
@ Mikes Antwort ist richtig, aber zu ungenau. Es stimmt, dass Python 3.3+ implizite Namespace-Pakete unterstützt , mit denen ein Paket ohne
__init__.py
Datei erstellt werden kann.Dies gilt jedoch NUR für leere
__init__.py
Dateien. So LEER__init__.py
- Dateien sind nicht mehr notwendig und kann weggelassen werden. Wenn Sie beim Importieren des Pakets oder eines seiner Module oder Unterpakete ein bestimmtes Initialisierungsskript ausführen möchten, benötigen Sie weiterhin ein__init__.py
Datei. Dies ist eine großartige Antwort auf den Stapelüberlauf, warum Sie eine__init__.py
Datei verwenden möchten, um eine weitere Initialisierung durchzuführen, falls Sie sich fragen, warum dies in irgendeiner Weise nützlich ist.Beispiel für die Verzeichnisstruktur:
parent_package/child_package/__init__.py
::BEISPIELE
Die folgenden Beispiele zeigen, wie das Initialisierungsskript ausgeführt wird, wenn das
child_package
oder eines seiner Module importiert wird.Beispiel 1 :
Beispiel 2 :
quelle
run_script.py
gleiche Verzeichnis wieparent_package
kann ich einfach wiefrom parent_package.child_package import child1
ohne importieren__init__.py
?child1.py
,child2.py
anstatt nur ihren Code__init__
direkt in .py zusammenzustellen.__init__
nicht relative Importe sein, dhfrom . import child1
? Der absolute Import gibt mirModuleNotFoundError
(in Python 3.6)__init__.py
manchmal noch ein Leerzeichen benötigt, beispielsweise wenn Sie einen Unterordner als Paket bezeichnen möchten. Wenn ich zum Beispiel ausgeführt habe, hatpython -m test.foo
es nicht funktioniert, bis ich ein leeres__init__.py
unter dem Testordner erstellt habe. Und ich spreche hier von der Version 3.6.6!Wenn Sie
setup.py
in Ihrem Projekt haben und es darin verwendenfind_packages()
, ist es erforderlich,__init__.py
in jedem Verzeichnis eine Datei zu haben, damit Pakete automatisch gefunden werden.UPD : Wenn Sie implizite Namespace-Pakete verwenden möchten, ohne diese
__init__.py
nur verwenden zu müssenfind_namespace_packages()
stattdessen verwenden zu müssenDocs
quelle
Ich würde sagen, dass man das
__init__.py
nur weglassen sollte, wenn man das implizite Namespace-Paket haben möchte . Wenn Sie nicht wissen, was es bedeutet, möchten Sie es wahrscheinlich nicht und sollten daher das__init__.py
Even in Python 3 weiterhin verwenden.quelle