Warum sollte ich Python-Code in __init__.py-Dateien einfügen?

73

Ich suche nach der Art des Codes, den ich in __init__.pyDateien einfügen würde, und welche bewährten Methoden diesbezüglich gelten. Oder ist es im Allgemeinen eine schlechte Praxis?

Jeder Verweis auf bekannte Dokumente, die dies erklären, wird ebenfalls sehr geschätzt.

webDevelSouth
quelle
2
mögliches Duplikat von Wofür ist init .py?
Aamir

Antworten:

65

Bibliotheken und Frameworks verwenden normalerweise Initialisierungscode in __init__.pyDateien , um die interne Struktur sauber zu verbergen und dem Benutzer eine einheitliche Oberfläche zu bieten .

Nehmen wir das Beispiel des Django-Formularmoduls . Verschiedene Funktionen und Klassen im Formularmodul werden basierend auf ihrer Klassifizierung in verschiedenen Dateien definiert.

forms/
  __init__.py
  extras/
    ...
  fields.py
  forms.py
  widgets.py
  ...

Wenn Sie nun ein Formular erstellen möchten, müssen Sie wissen, in welcher Datei jede Funktion definiert ist, und Ihr Code zum Erstellen eines Kontaktformulars muss ungefähr so ​​aussehen (was unpraktisch und hässlich ist).

 class CommentForm(forms.forms.Form):
    name = forms.fields.CharField() 
    url = forms.fields.URLField()
    comment = forms.fields.CharField(widget=forms.widgets.Textarea) 

Stattdessen können Sie in Django direkt aus dem Formular-Namespace auf verschiedene Widgets, Formulare, Felder usw. verweisen.

from django import forms

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)

Wie ist das möglich? Um dies zu ermöglichen, fügt Django der forms/__init__.pyDatei die folgende Anweisung hinzu, die alle Widgets, Formulare, Felder usw. in den formsNamespace importiert .

from widgets import *
from fields import *
from forms import *
from models import *

Wie Sie sehen, vereinfacht dies Ihr Leben beim Erstellen der Formulare, da Sie sich jetzt keine Gedanken mehr darüber machen müssen, wo jede Funktion / Klasse definiert ist, und alle diese Funktionen direkt aus dem formsNamespace verwenden müssen. Dies ist nur ein Beispiel, aber Sie können Beispiele wie diese in anderen Frameworks und Bibliotheken sehen.

Praveen Gollakota
quelle
11

Eine der besten Methoden in diesem Bereich besteht darin, alle benötigten Klassen aus Ihrer Bibliothek zu importieren ( siehe beispielsweise Mongoengine ). Ein Benutzer Ihrer Bibliothek kann dies also tun:

from coollibrary import OneClass, SecondClass

Anstatt von

from coollibrary.package import OneClass
from coollibrary.anotherpackage import SecondClass

Gute Praktiken sind auch in der __init__.pyVersionskonstante enthalten

Darvin
quelle
Was meinst du mit Versionskonstante? Könnten Sie bitte diese Aussage klären?
thanos.a vor
5
  1. Der Einfachheit halber: Die anderen Benutzer müssen den genauen Standort Ihrer Funktionen 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 add () von aufrufen

    from your_package import add
    

    ohne file1 zu kennen, wie

    from your_package.file1 import add
    
  2. Legen Sie etwas zum Initialisieren. Zum Beispiel die Protokollierung (dies sollte in die oberste Ebene gestellt werden):

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