Ich bin neu in Python, da ich die Fähigkeiten erweitern möchte, die ich mit R gelernt habe. In RI werden häufig eine Reihe von Bibliotheken geladen, was manchmal zu Konflikten mit Funktionsnamen führt.
Was ist die beste Vorgehensweise in Python? Ich habe einige spezifische Variationen gesehen, zwischen denen ich keinen Unterschied sehe
import pandas
, from pandas import *
Und from pandas import DataFrame
Was sind die Unterschiede zwischen den ersten beiden und sollte ich nur importieren, was ich brauche. Was wären die schlimmsten Konsequenzen für jemanden, der kleine Programme zur Datenverarbeitung und zur Berechnung einfacher Statistiken erstellt?
AKTUALISIEREN
Ich habe diesen ausgezeichneten Leitfaden gefunden . Es erklärt alles.
import pandas
undfrom pandas import DataFrame
beide sind okay. Die zweite Formfrom pandas import *
ist normalerweise nicht zu empfehlen, da sie nur alles in den globalen Namespace zieht.Antworten:
import pandas
Importiert das Pandas-Modul unter dem Pandas-Namespace, sodass Sie Objekte innerhalb von Pandas mit aufrufen müssenpandas.foo
.from pandas import *
Importiert alle Objekte aus dem Pandas-Modul in Ihren aktuellen Namespace, sodass Sie Objekte innerhalb von Pandas nur mit aufrufenfoo
. Beachten Sie, dass dies unerwartete Folgen haben kann, wenn zwischen Ihrem aktuellen Namespace und dem Pandas-Namespace Namenskonflikte bestehen.from pandas import DataFrame
ist das gleiche wie oben, importiert jedoch nurDataFrame
(anstelle von allem) in Ihren aktuellen Namespace.Meiner Meinung nach ist die erste im Allgemeinen die beste Vorgehensweise, da die verschiedenen Module in Ihrem Code gut unterteilt sind.
quelle
Nachteil jeder Form
Beim Lesen des Codes anderer Personen (und dieser Personen verwenden sehr unterschiedliche Importstile) sind mir bei jedem der Stile die folgenden Probleme aufgefallen:
import modulewithaverylongname
wird den Code weiter unten mit dem langen Modulnamen (z. B.concurrent.futures
oderdjango.contrib.auth.backends
) überladen und die Lesbarkeit an diesen Stellen verringern.from module import *
gibt mir keine Chance, das zum Beispiel syntaktisch zu sehenclassA
undclassB
aus demselben Modul zu kommen und viel miteinander zu tun zu haben. Es macht das Lesen des Codes schwierig . (Dass Namen aus einem solchen Import möglicherweise Namen aus einem früheren Import beschatten, ist der geringste Teil dieses Problems.)from module import classA, classB, functionC, constantD, functionE
Überlastet mein Kurzzeitgedächtnis mit zu vielen Namen, denen ich mental zuweisenmodule
muss, um den Code kohärent zu verstehen.import modulewithaverylongname as mwvln
ist mir manchmal nicht ausreichend mnemonisch .Ein geeigneter Kompromiss
Basierend auf den obigen Beobachtungen habe ich den folgenden Stil in meinem eigenen Code entwickelt:
import module
ist der bevorzugte Stil, wenn der Modulname kurz ist, wie beispielsweise die meisten Pakete in der Standardbibliothek. Dies ist auch der bevorzugte Stil, wenn ich Namen aus dem Modul nur an zwei oder drei Stellen in meinem eigenen Modul verwenden muss. Klarheit übertrumpft dann die Kürze ( "Lesbarkeit zählt" ).import longername as ln
ist in fast allen anderen Fällen der bevorzugte Stil. Zum Beispiel könnte ichimport django.contrib.auth.backends as djcab
. Nach Definition des obigen Kriteriums 1 wird die Abkürzung häufig verwendet und ist daher ausreichend leicht zu merken.Nur diese beiden Stile sind gemäß "Explizit ist besser als implizit" vollständig pythonisch . Regel.
from module import xx
kommt immer noch manchmal in meinem Code vor. Ich benutze es in Fällen, in denen sogar dasas
Format übertrieben erscheint. Das bekannteste Beispiel istfrom datetime import datetime
(aber wenn ich mehr Elemente benötige, werde ich es tunimport datetime as dt
).quelle
from module import xx
nur, wenn ich eine eigene Klasse importiere, die in einer anderen Datei definiert ist.from <package> import <module>
, insbesondere wenn das Modul mehrere Unterpakete tief ist. Ich würde viel lieber tippenfile_generators.Random()
alslibraries.file_utils.generators.file_generators.Random()
, also würde ich nur verwendenfrom libraries.file_utils.generators import file_generators
.Im Allgemeinen ist es besser, explizite Importe durchzuführen. Wie in:
import pandas frame = pandas.DataFrame()
Oder:
from pandas import DataFrame frame = DataFrame()
Eine andere Option in Python, wenn Sie widersprüchliche Namen haben, ist der Import von x als y:
from pandas import DataFrame as PDataFrame from bears import DataFrame as BDataFrame frame1 = PDataFrame() frame2 = BDataFrame()
quelle
Hier sind einige Empfehlungen aus dem PEP8 Style Guide.
Importe sollten normalerweise in getrennten Zeilen erfolgen , z.
Yes: import os import sys No: import sys, os
aber es ist okay
from subprocess import Popen, PIPE
Importe werden immer am Anfang der Datei platziert, direkt nach Modulkommentaren und Dokumentzeichenfolgen sowie vor Modulglobalen und -konstanten.
Absolute Importe werden empfohlen.
Sie sind besser lesbar und erleichtern das Debuggen, indem sie bessere Fehlermeldungen geben, falls Sie das Importsystem durcheinander bringen.
import mypkg.sibling from mypkg import sibling from mypkg.sibling import example
oder explizite relative Importe
from . import sibling from .sibling import example
Implizite relative Importe sollten niemals verwendet werden und werden in Python 3 entfernt.
No: from ..grand_parent_package import uncle_package
Wildcard-Importe (
from <module> import *
) sollten vermieden werden , da sie unklar machen, welche Namen im Namespace vorhanden sind, was sowohl die Leser als auch viele automatisierte Tools verwirrt.Einige Empfehlungen über
lazy imports
von Python Speed - Performance - Tipps.Das unten angegebene Szenario ist auf der Seite erläutert.
>>> def doit1(): ... import string ... string.lower('Python') ... >>> import string >>> def doit2(): ... string.lower('Python') ... >>> import timeit >>> t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()') >>> t.timeit() 11.479144930839539 >>> t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()') >>> t.timeit() 4.6661689281463623
quelle
from A import B
entspricht im Wesentlichen den folgenden drei Aussagen
import A B = A.B del A
Das ist es, das ist alles.
quelle
from A import B
wirdA
in den globalen Namespace importiert undB
auch. Sie können immer noch tunA.C
(oder auchA.B
wenn SieB
from itertools import imap >>> itertools <module 'itertools' (built-in)> >>> imap itertools.imap >>> itertools.starmap itertools.starmap
del A
Sie sind alle in unterschiedlichen Kontexten geeignet (weshalb sie alle verfügbar sind). Es gibt kein tiefes Leitprinzip außer allgemeinen Mutterschaftserklärungen zu Klarheit, Wartbarkeit und Einfachheit. Einige Beispiele aus meinem eigenen Code:
import sys, os, re, itertools
Vermeidet Namenskollisionen und bietet eine sehr prägnante Möglichkeit, eine Reihe von Standardmodulen zu importieren.from math import *
Lass michsin(x)
stattmath.sin(x)
in mathematisch schwerem Code schreiben . Das wird ein bisschen heikel, wenn ich auch numpy importiere, was sich bei einigen davon verdoppelt, aber es geht mich nichts an, da es sich im Allgemeinen sowieso um die gleichen Funktionen handelt. Außerdem neige ich dazu, der numpy-Dokumentation zu folgen, dieimport numpy as np
das Problem vollständig umgeht .from PIL import Image, ImageDraw
nur, weil die PIL-Dokumentation auf diese Weise ihre Beispiele präsentiert.quelle
sin(x)
anstatt ,math.sin(x)
warum nicht nutzenfrom math import sin
?sin
. Wenn ich nur eine Handvoll Symbole möchte, könnte ich jedes als Komma-Liste importieren, aber normalerweise kann ich nicht herausfinden, welche ich benötige.*
ist praktisch, wenn auch etwas faul.