Es wird empfohlen, nicht import *
in Python zu verwenden.
Kann jemand bitte den Grund dafür mitteilen, damit ich es beim nächsten Mal vermeiden kann?
python
python-import
Software-Enthusiasten
quelle
quelle
import *
funktioniert nicht für mich in Python 2 oder 3.Antworten:
Weil es eine Menge Dinge in Ihren Namespace bringt (möglicherweise ein anderes Objekt aus dem vorherigen Import beschattet und Sie nichts davon wissen).
Weil Sie nicht genau wissen, was importiert wird, und nicht leicht finden können, von welchem Modul eine bestimmte Sache importiert wurde (Lesbarkeit).
Weil Sie keine coolen Tools verwenden können
pyflakes
, um Fehler in Ihrem Code statisch zu erkennen.quelle
numpy.any
Schatten gebissen ,any
wenn sie dies tun,from numpy import *
oder ein "hilfreiches" Tool erledigt dies für sie.import *
die Reihenfolge derimport
Anweisungen signifikant ... selbst für Standardbibliotheksmodule, denen die Importreihenfolge normalerweise egal ist . Etwas so Unschuldiges wie das Alphabetisieren Ihrerimport
Aussagen könnte Ihr Drehbuch brechen, wenn ein ehemaliges Opfer des Importkrieges der einzige Überlebende wird. (Selbst wenn Ihr Skript jetzt funktioniert und sich nie ändert, kann es später plötzlich fehlschlagen, wenn das importierte Modul einen neuen Namen einführt, der einen ersetzt, auf den Sie sich verlassen haben.)Nach dem Zen von Python :
... kann man damit sicher nicht streiten?
quelle
use strict
(JavaScriptvar
) hinzugefügt hat . Abgesehen davon ist Python natürlich nicht typenlos (es ist tatsächlich stark typisiert). Selbst wenn Sie Recht hätten, würde dies dem in dieser Antwort zitierten Zen von Python widersprechen.Sie gehen nicht
**locals()
auf Funktionen über, oder?Da Python keine "include" -Anweisung hat und der
self
Parameter explizit ist und die Gültigkeitsbereichsregeln recht einfach sind, ist es normalerweise sehr einfach, mit dem Finger auf eine Variable zu zeigen und festzustellen, woher dieses Objekt stammt - ohne andere Module zu lesen und ohne irgendeine der IDE (die ohnehin in der Art der Selbstbeobachtung begrenzt sind, weil die Sprache sehr dynamisch ist).Das
import *
bricht alles.Es gibt auch eine konkrete Möglichkeit, Fehler zu verbergen.
Wenn das Balkenmodul eines der Attribute "
os
", "mystuff
" usw. hat, überschreiben sie die explizit importierten Attribute und verweisen möglicherweise auf sehr unterschiedliche Dinge. Das Definieren__all__
in Balken ist oft sinnvoll - dies gibt an, was implizit importiert wird -, aber es ist immer noch schwierig zu verfolgen, woher Objekte kommen, ohne das Balkenmodul zu lesen und zu analysieren und seine Importe zu verfolgen . Ein Netzwerk vonimport *
ist das erste, was ich repariere, wenn ich die Verantwortung für ein Projekt übernehme.Versteht mich nicht falsch: Wenn die
import *
fehlen würden, würde ich weinen, um sie zu haben. Aber es muss vorsichtig verwendet werden. Ein guter Anwendungsfall besteht darin, eine Fassadenschnittstelle über einem anderen Modul bereitzustellen. Ebenso erfordert die Verwendung von bedingten Importanweisungen oder Importen in Funktions- / Klassennamensräumen ein wenig Disziplin.Ich denke, bei mittelgroßen bis großen Projekten oder kleinen Projekten mit mehreren Mitwirkenden ist ein Minimum an Hygiene in Bezug auf die statische Analyse erforderlich - mindestens Pyflakes oder besser noch ein ordnungsgemäß konfigurierter Pylint -, um mehrere Arten von Fehlern zu erkennen sie passieren.
Da dies Python ist - zögern Sie nicht, Regeln zu brechen und zu erkunden -, aber seien Sie vorsichtig bei Projekten, die sich verzehnfachen könnten. Wenn dem Quellcode die Disziplin fehlt, ist dies ein Problem.
quelle
execfile()
. Glücklicherweise wird es selten verwendet und ist in 3.x verschwunden.**vars()
, Globals einzuschließen, wenn sich die aufgerufene Funktion in einer anderen Datei befindet? : PEs ist in Ordnung,
from ... import *
in einer interaktiven Sitzung zu tun .quelle
doctest
Schnur? Wird dasimport *
in diesem Fall in einer "Sandbox" interpretiert? Vielen Dank.Das liegt daran, dass Sie den Namespace verschmutzen. Sie importieren alle Funktionen und Klassen in Ihren eigenen Namespace, was zu Konflikten mit den von Ihnen selbst definierten Funktionen führen kann.
Darüber hinaus denke ich, dass die Verwendung eines qualifizierten Namens für die Wartungsaufgabe klarer ist. Sie sehen in der Codezeile selbst, woher eine Funktion stammt, sodass Sie die Dokumente viel einfacher auschecken können.
Im Modul foo:
In Ihrem Code:
quelle
http://docs.python.org/tutorial/modules.html
quelle
Angenommen, Sie haben den folgenden Code in einem Modul namens foo:
und dann haben Sie in Ihrem eigenen Modul:
Sie haben jetzt ein schwer zu debuggendes Modul, das so aussieht, als ob es lxml's etree enthält, aber stattdessen wirklich ElementTree.
quelle
Das sind alles gute Antworten. Ich werde hinzufügen, dass der Umgang mit Code in Python
import *
sehr schwierig ist , wenn man neuen Leuten das Codieren beibringt . Selbst wenn Sie oder sie den Code nicht geschrieben haben, ist er immer noch ein Stolperstein.Ich bringe Kindern (ungefähr 8 Jahre alt) bei, in Python zu programmieren, um Minecraft zu manipulieren. Ich möchte ihnen eine hilfreiche Codierungsumgebung geben, mit der sie arbeiten können ( Atom Editor ) und die REPL-gesteuerte Entwicklung (über bpython ) lehren . In Atom finde ich, dass die Hinweise / Vervollständigungen genauso effektiv funktionieren wie bpython. Glücklicherweise lässt sich Atom im Gegensatz zu einigen anderen statistischen Analysewerkzeugen nicht täuschen
import *
.Allerdings läßt dieses Beispiel nehmen ... In dieser Wrapper sie
from local_module import *
ein Bündel Module einschließlich dieser Liste von Blöcken . Ignorieren wir das Risiko von Namespace-Kollisionen. Auffrom mcpi.block import *
diese Weise machen sie diese gesamte Liste der obskuren Arten von Blöcken zu etwas, das Sie sich ansehen müssen, um zu wissen, was verfügbar ist. Wenn sie stattdessen verwendet hättenfrom mcpi import block
, könnten Sie eingeben,walls = block.
und dann würde eine Autovervollständigungsliste angezeigt.quelle
Verstanden die gültigen Punkte, die die Leute hier setzen. Ich habe jedoch ein Argument, dass "Sternimport" manchmal nicht immer eine schlechte Praxis ist:
const.py
:import const
, muss ich es für jede Konstante als bezeichnenconst.SOMETHING
, was wahrscheinlich nicht der bequemste Weg ist.from const import SOMETHING_A, SOMETHING_B ...
, dann ist es offensichtlich viel zu ausführlich und macht den Zweck der Strukturierung zunichte.from const import *
eine bessere Wahl sein kann, a zu tun .quelle
Es ist aus zwei Gründen eine sehr schlechte Praxis:
Zu Punkt 1 : Sehen wir uns ein Beispiel dafür an:
Hier auf dem Sehen Sie den Code nicht wird eine Idee in Bezug auf von dem Modul erhalten
b
,c
undd
tatsächlich gehört.Auf der anderen Seite, wenn Sie es mögen:
Es ist viel sauberer für Sie und auch die neue Person, die Ihrem Team beitritt, hat eine bessere Idee.
Zu Punkt 2 : Sagen wir beides
module1
undmodule2
haben die Variable alsb
. Wenn ich es tue:Hier geht der Wert von
module1
verloren. Es ist schwer zu debuggen, warum der Code nicht funktioniert, selbst wenn erb
in deklariert istmodule1
und ich den Code geschrieben habe, der die Verwendung meines Codes erwartetmodule1.b
Wenn Sie dieselben Variablen in verschiedenen Modulen haben und nicht das gesamte Modul importieren möchten, können Sie sogar Folgendes tun:
quelle
Als Test habe ich ein Modul test.py mit 2 Funktionen A und B erstellt, die jeweils "A 1" und "B 1" drucken. Nach dem Importieren von test.py mit:
. . . Ich kann die beiden Funktionen als test.A () und test.B () ausführen, und "test" wird als Modul im Namespace angezeigt. Wenn ich also test.py bearbeite, kann ich es neu laden mit:
Aber wenn ich folgendes mache:
Es gibt keinen Verweis auf "test" im Namespace, daher gibt es keine Möglichkeit, ihn nach einer Bearbeitung neu zu laden (soweit ich das beurteilen kann), was in einer interaktiven Sitzung ein Problem darstellt. Während eine der folgenden:
fügt "test" bzw. "tt" als Modulnamen in den Namespace ein, wodurch ein erneutes Laden möglich ist.
Wenn ich mache:
Die Namen "A" und "B" werden im Namespace als Funktionen angezeigt . Wenn ich test.py bearbeite und den obigen Befehl wiederhole, werden die geänderten Versionen der Funktionen nicht neu geladen.
Der folgende Befehl löst eine Fehlermeldung aus.
Wenn jemand weiß, wie man ein mit "from module import *" geladenes Modul neu lädt, bitte posten. Andernfalls wäre dies ein weiterer Grund, das Formular zu vermeiden:
quelle
Wie in den Dokumenten vorgeschlagen, sollten Sie (fast) niemals
import *
im Produktionscode verwenden.Während der Import
*
aus einem Modul schlecht ist, ist der Import * aus einem Paket noch schlechter. Standardmäßig werdenfrom package import *
alle Namen importiert, die von den Paketen definiert wurden__init__.py
, einschließlich aller Submodule des Pakets, die von den vorherigen geladen wurdenimport
Anweisungen .Wenn der
__init__.py
Code eines Pakets jedoch eine Liste mit dem Namen definiert__all__
, wird davon ausgegangen, dass es sich um die Liste der Submodulnamen handelt, die importiert werden sollen, wenn siefrom package import *
auftreten.Betrachten Sie dieses Beispiel (vorausgesetzt, es ist nicht
__all__
definiert insound/effects/__init__.py
):Die letzte Anweisung importiert die Module
echo
undsurround
in den aktuellen Namespace (möglicherweise werden vorherige Definitionen überschrieben), da siesound.effects
bei derimport
Ausführung der Anweisung im Paket definiert werden .quelle