3676 Stimmen

Wofür ist __init__.py da?

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

36 Stimmen

Gemäß dem unten stehenden Kommentar von @Rob_before_edits und dieser Stackoverflow-Thread 37139786 scheint es, dass init .py wird für Python 3.3+ nicht mehr benötigt.

24 Stimmen

Paket ohne __init__ es Namensraum Paket , nicht ein normales Paket . Das ist nicht dasselbe wie @methane mit hier ein Beispiel .

4 Stimmen

@Rainning Ein Namespace-Paket unterscheidet sich nicht grundlegend von einem normalen Paket. Es ist nur eine andere Art, Pakete zu erstellen. Sobald ein Namespace-Paket erstellt ist, gibt es keinen funktionalen Unterschied mehr zwischen ihm und einem regulären Paket.

2002voto

Loki Punkte 28114

Früher war es ein obligatorischer Bestandteil eines Pakets ( altes, vor 3.3 erstelltes "normales Paket" no neueres 3.3+ "Namensraum-Paket" ).

Hier ist die Dokumentation.

Python definiert zwei Arten von Paketen, reguläre Pakete und Namespace-Pakete. Reguläre Pakete sind traditionelle Pakete, wie sie in Python 3.2 und früher existierten. Ein reguläres Paket ist typischerweise als ein Verzeichnis implementiert, das eine __init__.py Datei. Wenn ein reguläres Paket importiert wird, wird diese __init__.py Datei wird implizit ausgeführt, und die darin definierten Objekte werden an Namen im Namensraum des Pakets gebunden. Die __init__.py Datei kann den gleichen Python-Code enthalten wie jedes andere Modul auch, und Python fügt dem Modul beim Import einige zusätzliche Attribute hinzu.

Aber klicken Sie einfach auf den Link, er enthält ein Beispiel, weitere Informationen und eine Erklärung von Namespace-Paketen, der Art von Paketen ohne __init__.py .

235 Stimmen

Was bedeutet das? "Dies wird gemacht, um zu verhindern, dass Verzeichnisse mit einem gemeinsamen Namen, wie z.B. string, unbeabsichtigt gültige Module verbergen, die später im Modul-Suchpfad auftauchen"?

126 Stimmen

@CarlG Python sucht eine Liste der Verzeichnisse um Namen z.B. in Import-Anweisungen aufzulösen. Da es sich dabei um beliebige Verzeichnisse handeln kann, die vom Endbenutzer hinzugefügt werden können, müssen sich die Entwickler um Verzeichnisse kümmern, die zufällig den gleichen Namen wie ein gültiges Python-Modul haben, wie z.B. 'string' im Beispiel der Docs. Um dies zu vermeiden, werden Verzeichnisse ignoriert, die keine Datei mit dem Namen _ _ init _ _.py (ohne Leerzeichen) enthalten, selbst wenn diese leer ist.

249 Stimmen

@CarlG Versuchen Sie dies. Legen Sie ein Verzeichnis namens 'datetime' an und erstellen Sie darin zwei leere Dateien, die Datei init.py (mit Unterstrichen) und datetime.py. Öffnen Sie nun einen Interpreter, importieren Sie sys, und geben Sie sys.path.insert(0, '/path/to/datetime') und ersetzen Sie diesen Pfad durch den Pfad zu dem Verzeichnis, das Sie gerade erstellt haben. Versuchen Sie nun etwas wie from datetime import datetime;datetime.now() . Sie sollten einen AttributeError erhalten (weil Ihre leere Datei jetzt importiert wird). Wenn Sie diese Schritte wiederholen würden, ohne die leere Init-Datei zu erstellen, würde dies nicht passieren. Genau das soll damit verhindert werden.

1252voto

caritos Punkte 11254

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

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

y mydir auf Ihrem Pfad ist, können Sie den Code in module.py als

import spam.module

o

from spam import module

Wenn Sie die __init__.py Datei, sucht Python nicht mehr nach Untermodulen in diesem Verzeichnis, so dass Versuche, das Modul zu importieren, fehlschlagen.

Le site __init__.py ist in der Regel leer, kann aber verwendet werden, um ausgewählte Teile des Pakets unter einem passenderen Namen zu exportieren, Komfortfunktionen zu enthalten usw. Im obigen Beispiel kann auf den Inhalt des init-Moduls wie folgt zugegriffen werden

import spam

auf Grund ce

173 Stimmen

Aktualisierung: Die Datei __init__.py wurde unter Python 2.X benötigt und wird immer noch unter Python 2.7.12 benötigt (ich habe es getestet), aber es wird ab (angeblich) Python 3.3 nicht mehr benötigt und ist unter Python 3.4.3 nicht erforderlich (ich habe es getestet). Siehe stackoverflow.com/questions/37139786 für weitere Einzelheiten.

2 Stimmen

Warum haben Sie import spam innen` init .py`, was ist seine Hilfe

0 Stimmen

@alper er hat nicht import spam innerhalb __init__.py hat er sie in der Datei main.py oder einer anderen Datei, die den Inhalt von spam . Sie können behandeln spam als Objekt importieren und verwenden Sie Funktionen, die in spam/__init__.py

670voto

Nathan Gould Punkte 7205

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

Ein Beispiel

Hier ein Beispiel aus einem meiner Projekte, bei dem ich häufig eine sessionmaker genannt. Session um mit meiner Datenbank zu interagieren. Ich habe ein "Datenbank"-Paket mit ein paar 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 ich definiere Session Hier kann ich eine neue Sitzung mit der folgenden Syntax starten. Dieser Code würde sowohl innerhalb als auch außerhalb des Paketverzeichnisses "database" ausgeführt werden.

from database import Session
session = Session()

Natürlich ist dies eine kleine Erleichterung - die Alternative wäre die Definition von Session in einer neuen Datei wie "create_session.py" in meinem Datenbankpaket, und starten Sie neue Sitzungen mit:

from database.create_session import Session
session = Session()

Weitere Lektüre

Es gibt einen ziemlich interessanten reddit-Thread über die angemessene Verwendung 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 zu sein, dass __init__.py Dateien sollten sehr dünn sein, um nicht gegen die Philosophie "explizit ist besser als implizit" zu verstoßen.

8 Stimmen

engine , sessionmaker , create_engine et os können alle auch von database Nun... es sieht so aus, als hättest du diesen Namensraum durcheinander gebracht.

19 Stimmen

@ArtOfWarfare, können Sie verwenden __all__ = [...] um zu begrenzen, was importiert wird mit import * . Aber abgesehen davon, ja, Sie sind mit einem chaotischen Top-Level-Namensraum links.

4 Stimmen

@NathanGould Sie könnten auch einfach führende Unterstrichvariablen verwenden, die nicht von import * standardmäßig. Beispiel: import os as _os und verwenden _os innerhalb der __init__.py Modul anstelle von os .

527voto

flycee Punkte 9887

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

  1. Der Einfachheit halber: Die anderen Benutzer müssen nicht wissen, wo genau sich Ihre Funktionen in Ihrer Pakethierarchie befinden ( Dokumentation ).

    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 add() aufrufen, indem sie

     from your_package import add

    ohne file1 zu kennen, wie

     from your_package.file1 import add
  2. Wenn etwas initialisiert werden soll, z. B. die Protokollierung (die auf der obersten Ebene erfolgen sollte):

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

21 Stimmen

Oh, bevor ich Ihre Antwort gelesen habe, dachte ich, dass der explizite Aufruf einer Funktion von ihrem Standort aus eine gute Praxis ist.

11 Stimmen

@Aerin es wäre besser, kurze Aussagen (oder, in diesem Fall, subjektive Schlussfolgerungen) nicht immer für wahr zu halten. Importieren von __init__.py kann manchmal nützlich sein, aber nicht immer.

2 Stimmen

Was drin sein muss init .py?

186voto

Can Berk Güder Punkte 103655

Le site __init__.py Datei bewirkt, dass Python Verzeichnisse, die sie enthalten, als Module behandelt.

Außerdem ist dies die erste Datei, die in einem Modul geladen wird. Sie können sie also verwenden, um Code auszuführen, der bei jedem Laden eines Moduls ausgeführt werden soll, oder um die zu exportierenden Untermodule anzugeben.

24 Stimmen

Ich denke, die init .py lässt Python Verzeichnisse als Pakete y no Module . Siehe docs.python.org/3/lehrgang/modules.html

14 Stimmen

"Alle Pakete sind Module, aber nicht alle Module sind Pakete" - seltsam, aber wahr.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X