2009-11-09 6 views
19

Von den verschiedenen Möglichkeiten, Code zu importieren, gibt es einige Möglichkeiten, die im Vergleich zu anderen vorzuziehen sind? Dieser Link http://effbot.org/zone/import-confusion.htm kurz besagt, dassPython (und Django) beste Importpraktiken

from foo.bar import MyClass 

nicht der bevorzugte Weg ist MyClass unter normalen Umständen zu importieren oder wenn Sie wissen, was Sie tun. (Vielmehr ist eine bessere Art und Weise möchte:

import foo.bar as foobaralias 

und dann im Code für den Zugriff auf MyClass verwenden

foobaralias.MyClass 

)

Kurz gesagt, scheint es, dass die oben genannten Link ist sagen, es ist in der Regel besser, alles aus einem Modul zu importieren, anstatt nur Teile des Moduls.

Allerdings ist dieser Artikel, den ich verlinkte, wirklich alt.

Ich habe auch gehört, dass es besser ist, im Kontext von Django-Projekten stattdessen nur die Klassen zu importieren, die Sie verwenden möchten, anstatt das ganze Modul. Es wurde gesagt, dass diese Form hilft, zirkuläre Importfehler zu vermeiden oder zumindest das Django-Importsystem weniger fragil zu machen. Es wurde darauf hingewiesen, dass Djangos eigener Code "von x import y" gegenüber "import x" zu bevorzugen scheint.

Angenommen, das Projekt, an dem ich arbeite, verwendet keine speziellen Funktionen von __init__.py ... (alle unsere __init__.py Dateien sind leer), welche Importmethode sollte ich bevorzugen, und warum?

Antwort

5

Für mich ist es abhängig von der Situation. Wenn es eine eindeutig benannte Methode/Klasse ist (d. H. Nicht process() oder etwas Ähnliches), und Sie werden es verwenden ein Los, dann speichern Sie Eingabe und tun Sie einfach from foo import MyClass.

Wenn Sie mehrere Dinge von einem Modul importieren, ist es wahrscheinlich besser, nur das Modul zu importieren und module.bar, module.foo, module.baz usw. zu machen, um den Namensraum sauber zu halten.

Sie haben auch gesagt

Es ist gesagt worden, dass diese Form Kreisimportfehler oder zumindest macht Importsystem weniger zerbrechlich das django vermeiden hilft. Es wurde darauf hingewiesen, dass Djangos eigener Code "von x import y" gegenüber "import x" zu bevorzugen scheint.

Ich sehe nicht, wie die eine oder andere Art helfen würde, zirkuläre Importe zu verhindern. Der Grund ist, dass selbst wenn Sie from x import y tun, wird ALL von x importiert. Nur y wird in den aktuellen Namespace gebracht, aber das gesamte Modul x wird verarbeitet. Probieren Sie dieses Beispiel:

In test.py, legen Sie die folgenden Schritte aus:

def a(): 
    print "a" 

print "hi" 

def b(): 
    print "b" 

print "bye" 

dann in 'runme.py' setzen:

from test import b 

b() 

Dann tun nur python runme.py

Sie sehen folgende Ausgabe:

hi 
bye 
b 

So wurde alles in test.py ausgeführt, obwohl Sie nur b

2

Der Vorteil der letzteren ist, dass der Ursprung von MyClass expliziter ist. Der erste setzt MyClass in den aktuellen Namespace, so dass der Code MyClass einfach nur verwenden kann. Es ist also weniger offensichtlich für jemanden, der den Code liest, in dem MyClass definiert ist.

13

Zuerst und primäre, Regel der Importe: nie verwenden Sie from foo import *.

Der Artikel diskutiert das Thema der zyklischen Importe, die heute noch in schlecht strukturiertem Code existieren. Ich mag zyklische Importe nicht; ihre Anwesenheit ist ein starkes Zeichen dafür, dass ein Modul zu viel tut und aufgeteilt werden muss. Wenn Sie aus irgendeinem Grund mit einem Code mit zyklischen Importen arbeiten müssen, der nicht neu arrangiert werden kann, ist import foo die einzige Option. In den meisten Fällen gibt es keinen großen Unterschied zwischen import foo und from foo import MyClass. Ich ziehe die zweiten, weil es weniger Tipp beteiligt, aber es gibt ein paar Gründe, warum ich die ersten verwenden könnte:

  • Das Modul und Klasse/Wert unterschiedliche Namen haben. Es kann für die Leser schwierig sein, sich daran zu erinnern, woher ein bestimmter Import stammt, wenn der Name des importierten Werts nicht mit dem Modul verknüpft ist.

    • Gut: import myapp.utils as utils; utils.frobnicate()
    • Gut: import myapp.utils as U; U.frobnicate()
    • Bad: from myapp.utils import frobnicate
  • Du viele Werte von einem Modul zu importieren. Rette deine Finger und die Augen des Lesers.

    • Bad: from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada
+0

importiert haben Eine bestimmte Ausnahme dazu könnte in Django sein, wo Sie eine Klasse importieren, die ein Modell implementiert (das eine Datenbanktabelle darstellt). In diesem Fall ist es besser zu sagen "from django.contrib.auth import User". Aber wie gesagt, dies ist eine für eine bestimmte Umgebung spezifische Konvention. –

+2

was ist mit 'von myapp importieren utils; utils.frobnicate() '? – Joschua

+1

Joschua: das ist auch in Ordnung, da jeder, der es durchliest, sehen kann, woher "Frobnicate" importiert wird. –