PEP 8 sagt:
- Importe werden immer am Anfang der Datei platziert, direkt nach Modulkommentaren und Dokumentzeichenfolgen sowie vor Modulglobalen und -konstanten.
Gelegentlich verstoße ich gegen PEP 8. Manchmal importiere ich Dinge in Funktionen. In der Regel mache ich das, wenn es einen Import gibt, der nur innerhalb einer einzelnen Funktion verwendet wird.
Irgendwelche Meinungen?
BEARBEITEN (der Grund, warum ich das Importieren in Funktionen für eine gute Idee halte):
Hauptgrund: Es kann den Code klarer machen.
- Wenn ich mir den Code einer Funktion anschaue, frage ich mich vielleicht: "Was ist Funktion / Klasse xxx?" (xxx wird innerhalb der Funktion verwendet). Wenn ich alle meine Importe oben im Modul habe, muss ich dort nachsehen, was xxx ist. Dies ist eher ein Problem bei der Verwendung
from m import xxx
. Das Sehenm.xxx
in der Funktion sagt mir wahrscheinlich mehr. Je nachdem, wasm
ist: Ist es ein bekanntes Top-Level-Modul / Paket (import m
)? Oder ist es ein Untermodul / Paket (from a.b.c import m
)? - In einigen Fällen kann das Verständnis der Funktion erleichtert werden, wenn diese zusätzlichen Informationen ("Was ist xxx?") In der Nähe des Verwendungsortes von xxx verwendet werden.
python
conventions
Codeape
quelle
quelle
Antworten:
Auf lange Sicht werden Sie es zu schätzen wissen, dass die meisten Ihrer Importe ganz oben in der Datei stehen. Auf diese Weise können Sie auf einen Blick erkennen, wie kompliziert Ihr Modul ist, wenn es importiert werden muss.
Wenn ich einer vorhandenen Datei neuen Code hinzufüge, führe ich den Import normalerweise dort durch, wo er benötigt wird. Wenn der Code erhalten bleibt, mache ich die Dinge dauerhafter, indem ich die Importzeile an den Anfang der Datei verschiebe.
Ein weiterer Punkt, ich bevorzuge es, eine
ImportError
Ausnahme zu erhalten, bevor Code ausgeführt wird - als Überprüfung der Integrität. Dies ist also ein weiterer Grund, oben zu importieren.Ich benutze
pyChecker
, um nach nicht verwendeten Modulen zu suchen.quelle
Es gibt zwei Fälle, in denen ich diesbezüglich gegen PEP 8 verstoße:
import pdb; pdb.set_trace()
Dies ist praktisch, da ich nichtimport pdb
jedes Modul, das ich debuggen möchte, an die Spitze setzen möchte, und es ist leicht zu merken, den Import zu entfernen, wenn ich den Haltepunkt entferne.Außerhalb dieser beiden Fälle ist es eine gute Idee, alles an die Spitze zu setzen. Es macht die Abhängigkeiten klarer.
quelle
Hier sind die vier Importanwendungsfälle, die wir verwenden
import
(undfrom x import y
undimport x as y
) obenAuswahlmöglichkeiten für den Import. Oben.
Bedingter Import. Wird mit JSON, XML-Bibliotheken und dergleichen verwendet. Oben.
Dynamischer Import. Bisher haben wir nur ein Beispiel dafür.
Beachten Sie, dass dieser dynamische Import keinen Code einbringt, sondern komplexe Datenstrukturen, die in Python geschrieben wurden. Es ist wie ein eingelegtes Datenelement, nur dass wir es von Hand eingelegt haben.
Dies befindet sich mehr oder weniger auch oben in einem Modul
Folgendes tun wir, um den Code klarer zu gestalten:
Halten Sie die Module kurz.
Wenn ich alle meine Importe oben im Modul habe, muss ich dort nachsehen, um festzustellen, was ein Name ist. Wenn das Modul kurz ist, ist das einfach.
In einigen Fällen kann das Verständnis der Funktion erleichtert werden, wenn diese zusätzlichen Informationen in der Nähe des Verwendungsortes eines Namens vorhanden sind. Wenn das Modul kurz ist, ist das einfach.
quelle
Eines ist zu beachten: Unnötige Importe können zu Leistungsproblemen führen. Wenn dies also eine Funktion ist, die häufig aufgerufen wird, ist es besser, den Import ganz oben zu platzieren. Dies ist natürlich eine Optimierung. Wenn also ein gültiger Fall vorliegt, dass das Importieren innerhalb einer Funktion klarer ist als das Importieren am Anfang einer Datei, übertrifft dies in den meisten Fällen die Leistung.
Wenn Sie IronPython ausführen, wird mir gesagt, dass es besser ist, interne Funktionen zu importieren (da das Kompilieren von Code in IronPython langsam sein kann). Auf diese Weise können Sie möglicherweise einen Weg zum Importieren von Inside-Funktionen finden. Aber anders als das würde ich argumentieren, dass es sich einfach nicht lohnt, gegen Konventionen zu kämpfen.
Ein weiterer Punkt, den ich ansprechen möchte, ist, dass dies ein potenzielles Wartungsproblem sein kann. Was passiert, wenn Sie eine Funktion hinzufügen, die ein Modul verwendet, das zuvor nur von einer Funktion verwendet wurde? Denken Sie daran, den Import oben in die Datei einzufügen? Oder scannen Sie jede einzelne Funktion nach Importen?
FWIW, es gibt Fälle, in denen es sinnvoll ist, innerhalb einer Funktion zu importieren. Wenn Sie beispielsweise die Sprache in cx_Oracle festlegen möchten, müssen Sie vor dem Import eine NLS
_
LANG-Umgebungsvariable festlegen . Daher sehen Sie möglicherweise Code wie folgt:quelle
Ich habe diese Regel schon einmal für Module gebrochen, die sich selbst testen. Das heißt, sie werden normalerweise nur zur Unterstützung verwendet, aber ich definiere eine Hauptleitung für sie, damit Sie ihre Funktionalität testen können, wenn Sie sie selbst ausführen. In diesem Fall importiere ich manchmal
getopt
undcmd
nur in der Hauptsache, weil ich möchte, dass jemandem, der den Code liest, klar ist, dass diese Module nichts mit dem normalen Betrieb des Moduls zu tun haben und nur zum Testen enthalten sind.quelle
Aus der Frage nach dem zweimaligen Laden des Moduls - Warum nicht beides?
Ein Import am oberen Rand des Skripts zeigt die Abhängigkeiten an, und ein weiterer Import in der Funktion macht diese Funktion atomarer, ohne anscheinend einen Leistungsnachteil zu verursachen, da ein aufeinanderfolgender Import billig ist.
quelle
Solange es ist
import
und nichtfrom x import *
, sollten Sie sie oben platzieren. Es fügt dem globalen Namespace nur einen Namen hinzu, und Sie bleiben bei PEP 8. Wenn Sie ihn später an einem anderen Ort benötigen, müssen Sie nichts verschieben.Es ist keine große Sache, aber da es fast keinen Unterschied gibt, würde ich vorschlagen, das zu tun, was PEP 8 sagt.
quelle
from x import *
wird in einer Funktion eines SyntaxWarning erzeugen, zumindest 2,5 beträgt.Schauen Sie sich den alternativen Ansatz an, der in der SQLalchemie verwendet wird: Abhängigkeitsinjektion:
Beachten Sie, wie die importierte Bibliothek in einem Dekorator deklariert und als Argument an die Funktion übergeben wird !
Dieser Ansatz macht den Code sauberer und funktioniert auch 4,5-mal schneller als eine
import
Anweisung!Benchmark: https://gist.github.com/kolypto/589e84fbcfb6312532658df2fabdb796
quelle
In Modulen, die beide 'normale' Module sind und ausgeführt werden können (dh einen
if __name__ == '__main__':
Abschnitt haben), importiere ich normalerweise Module, die nur verwendet werden, wenn das Modul innerhalb des Hauptabschnitts ausgeführt wird.Beispiel:
quelle
Es gibt einen anderen (wahrscheinlich "Eck") Fall, in dem es für
import
selten verwendete Funktionen von Vorteil sein kann: Verkürzung der Startzeit.Ich bin einmal mit einem ziemlich komplexen Programm auf diese Wand gestoßen, das auf einem kleinen IoT-Server ausgeführt wird und Befehle von einer seriellen Leitung akzeptiert und Operationen ausführt, möglicherweise sehr komplexe Operationen.
Platzieren von
import
Anweisungen oben in Dateien, damit alle Importe vor dem Start des Servers verarbeitet werden. daimport
Liste aufgenommenjinja2
,lxml
,signxml
und andere „schwere Gewichte“ (und SoC war nicht sehr mächtig) Das bedeutete Minuten vor der ersten Anweisung tatsächlich ausgeführt.OTOH platzierte die meisten Importe in Funktionen. Ich konnte den Server in Sekundenschnelle auf der seriellen Leitung "am Leben" halten. Als die Module tatsächlich benötigt wurden, musste ich natürlich den Preis bezahlen (Hinweis: Dies kann auch durch das Laichen einer Hintergrundaufgabe, die
import
in Leerlaufzeit ausgeführt wird , gemildert werden ).quelle