Frage Wofür ist __init__.py?


Was ist __init__.py für in einem Python-Quellverzeichnis?


1411
2018-01-15 20:09


Ursprung


Antworten:


Es ist ein Teil eines Pakets. Hier ist die Dokumentation.

Das __init__.py Dateien werden benötigt, damit Python die Verzeichnisse als Pakete behandelt; Dies geschieht, um Verzeichnisse mit einem gemeinsamen Namen, wie z stringdurch das unabsichtliche Verbergen gültiger Module, die später (tiefer) auf dem Modulsuchpfad auftreten. Im einfachsten Fall __init__.py kann nur eine leere Datei sein, aber es kann auch einen Initialisierungscode für das Paket ausführen oder den __all__ Variable, später beschrieben.


975
2018-01-15 20:13



Dateien benannt __init__.py werden verwendet, um Verzeichnisse auf der Festplatte als Python-Paketverzeichnisse zu markieren. Wenn Sie die Dateien haben

mydir/spam/__init__.py
mydir/spam/module.py

und mydir Ist auf Ihrem Weg, können Sie den Code importieren module.py wie

import spam.module

oder

from spam import module

Wenn Sie das entfernen __init__.py Datei wird Python nicht mehr nach Submodulen in diesem Verzeichnis suchen, so dass Versuche, das Modul zu importieren, fehlschlagen.

Das __init__.py Datei ist in der Regel leer, kann aber verwendet werden, um ausgewählte Teile des Pakets unter einem bequemeren Namen, mit Komfortfunktionen usw. zu exportieren. Im obigen Beispiel kann auf den Inhalt des init-Moduls zugegriffen werden

import spam

beyogen auf Dies


597
2017-11-07 03:31



Zusätzlich zum Kennzeichnen eines Verzeichnisses als Python-Paket und zum Definieren __all__, __init__.py ermöglicht Ihnen, jede Variable auf der Paketebene zu definieren. Dies ist oft praktisch, wenn ein Paket etwas definiert, das häufig API-ähnlich importiert wird. Dieses Muster fördert die Einhaltung der Pythonic-Philosophie "flach ist besser als verschachtelt".

Ein Beispiel

Hier ist ein Beispiel aus einem meiner Projekte, in das ich häufig ein sessionmaker namens Session um mit meiner Datenbank zu interagieren. Ich habe ein "Datenbank" -Paket mit einigen Modulen geschrieben:

database/
    __init__.py
    schema.py
    insertions.py
    queries.py

Meine __init__.py enthält den folgenden Code:

import os

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

Da definiere ich Session Hier kann ich mit der folgenden Syntax eine neue Sitzung starten. Dieser Code wird innerhalb oder außerhalb des Paketverzeichnisses "database" ausgeführt.

from database import Session
session = Session()

Natürlich ist das eine kleine Annehmlichkeit - die Alternative wäre zu definieren Session in einer neuen Datei wie "create_session.py" in meinem Datenbankpaket und starte neue Sitzungen mit:

from database.create_session import Session
session = Session()

Weiterführende Literatur

Es gibt einen ziemlich interessanten reddit Thread, der die entsprechenden Anwendungen von __init__.py Hier:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

Die Mehrheitsmeinung scheint das zu sein __init__.py Die Dateien sollten sehr dünn sein, um eine Verletzung der Philosophie "Explizit ist besser als implizit" zu vermeiden.


366
2017-09-24 10:38



Es gibt 2 Hauptgründe dafür __init__.py

  1. Aus praktischen Gründen müssen die anderen Benutzer die genaue Position Ihrer Funktionen in Ihrer Pakethierarchie nicht kennen.

    your_package/
      __init__.py
      file1.py/
      file2.py/
        ...
      fileN.py
    
    # in __init__.py
    from file1 import *
    from file2 import *
    ...
    from fileN import *
    
    # in file1.py
    def add():
        pass
    

    dann können andere hinzufügen () durch

    from your_package import add
    

    ohne zu wissen, Datei1, wie

    from your_package.file1 import add
    
  2. Wenn Sie wollen, dass etwas initialisiert wird; zum Beispiel Protokollierung (die auf die oberste Ebene gesetzt werden sollte):

    import logging.config
    logging.config.dictConfig(Your_logging_config)
    

103
2018-04-08 08:29



Das __init__.py Datei macht Python behandeln Verzeichnisse, die es als Module enthalten.

Darüber hinaus ist dies die erste Datei, die in ein Modul geladen wird. Sie können damit Code ausführen, der bei jedem Laden eines Moduls ausgeführt werden soll, oder die zu exportierenden Submodule angeben.


87
2018-01-15 20:22



Seit Python 3.3, __init__.py ist nicht mehr erforderlich, um Verzeichnisse als importierbare Python-Pakete zu definieren.

Prüfen PEP 420: Implizite Namespacepakete:

Native Unterstützung für Paketverzeichnisse, die nicht benötigt werden __init__.py Markierdateien und kann automatisch mehrere Pfadsegmente umfassen (inspiriert durch verschiedene Ansätze von Drittanbietern für Namespacepakete, wie in PEP 420)

Hier ist der Test:

$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3

>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module

Verweise:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Ist __init__.py nicht für Pakete in Python 3 erforderlich? 


45
2017-10-12 06:36



In Python ist die Definition von Paket sehr einfach. Wie bei Java sind die hierarchische Struktur und die Verzeichnisstruktur identisch. Aber du musst haben __init__.py in einem Paket. Ich werde das erklären __init__.py Datei mit dem Beispiel unten:

package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py

__init__.py kann leer sein, solange es existiert. Es zeigt an, dass das Verzeichnis als ein Paket betrachtet werden sollte. Na sicher, __init__.py kann auch den passenden Inhalt einstellen.

Wenn wir eine Funktion in module_n1 hinzufügen:

def function_X():
    print "function_X in module_n1"
    return

Nach dem Rennen:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()

function_X in module_n1 

Dann folgten wir dem Hierarchiepaket und nannten module_n1 die Funktion. Wir können benutzen __init__.py in subPackage_b wie folgt:

__all__ = ['module_n2', 'module_n3']

Nach dem Rennen:

>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1

Daher unterliegt das Modul-Paket dem Import __init__.py Inhalt.


44
2018-01-09 11:45



__init__.py behandelt das Verzeichnis, in dem es sich befindet, als ein ladbares Modul.

Für Leute, die das Lesen von Code bevorzugen, lege ich fest Zwei-Bit-Alchemisten hier kommentieren.

$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$ 
$ rm /tmp/mydir/spam/__init__.py*
$ 
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>> 

35
2018-01-03 17:41



Wofür wird __init__.py verwendet?

Die primäre Verwendung von __init__.py besteht darin, Python-Pakete zu initialisieren. Der einfachste Weg, dies zu demonstrieren, ist, einen Blick auf die Struktur eines Standard-Python-Moduls zu werfen.

package/
    __init__.py
    file.py
    file2.py
    file3.py
    subpackage/
        __init__.py
        submodule1.py
        submodule2.py

Wie Sie in der obigen Struktur sehen können, ist die Aufnahme der __init__.py Datei in einem Verzeichnis zeigt dem Python-Interpreter an, dass das Verzeichnis wie ein Python-Paket behandelt werden soll

Was rein geht __init__.py?

__init__.py kann eine leere Datei sein, wird aber oft verwendet, um das für das Paket erforderliche Setup durchzuführen (Dinge importieren, Dinge in den Pfad laden usw.).

Eine gemeinsame Sache in Ihrem __init__.py ist es, ausgewählte Klassen, Funktionen usw. in die Paketebene zu importieren, damit sie bequem aus dem Paket importiert werden können.

Im obigen Beispiel können wir sagen, dass file.py die Klassendatei hat. Also ohne etwas in unserem __init__.py Sie würden mit dieser Syntax importieren:

from package.file import File

Sie können jedoch Datei in Ihr importieren __init__.py um es auf der Paketebene verfügbar zu machen:

# in your __init__.py
from file import File

# now import File from package
from package import File

Eine andere Sache, die zu tun ist, ist es, auf der Paketebene Unterpakete / Module mit dem zur Verfügung zu stellen __all__ Variable. Wenn der Interpeter ein sieht __all__ Variable in einem definiert __init__.py Es importiert die in der __all__ Variable, wenn Sie Folgendes tun:

from package import *

__all__ist eine Liste, die die Namen der Module enthält, die mit importiert werden sollen *. Schauen wir uns also erneut unser Beispiel an, wenn wir die Submodule in das Unterpaket importieren wollten __all__ Variable in subpackage/__init__.py wäre:

__all__ = ['submodule1', 'submodule2']

Mit dem __all__ Variable wie diese, wenn Sie durchführen

from subpackage import *

Es würde Submodul1 und Submodul2 importieren.

Wie du siehst __init__.py kann neben seiner primären Funktion, die angibt, dass ein Verzeichnis ein Modul ist, sehr nützlich sein.

Referenz


26
2017-12-17 06:09



Es erleichtert den Import anderer Python-Dateien. Wenn Sie diese Datei in ein Verzeichnis (zB Zeug) mit anderen py-Dateien gelegt haben, können Sie etwas wie stuff.other importieren.

root\
    stuff\
         other.py

    morestuff\
         another.py

Ohne das __init__.py Im Verzeichnis stuff konnten Sie other.py nicht importieren, da Python nicht weiß, wo der Quellcode für stuff ist und es nicht als Paket erkennen kann.


25
2018-01-15 20:18