Ich habe immer diese Methode verwendet:
from sys import argv
und verwenden Sie argv
mit nur argv . Es gibt jedoch eine Konvention, dies zu verwenden:
import sys
und das Argument von sys.argv
Die zweite Methode macht den Code selbst dokumentiert und ich (wirklich) halte mich daran. Aber der Grund, warum ich die erste Methode bevorzuge, ist, dass sie schnell ist, weil wir nur die benötigte Funktion importieren, anstatt das gesamte Modul zu importieren (das mehr nutzlose Funktionen enthält, die Python beim Importieren verschwenden wird). Beachten Sie, dass ich nur argv brauche und alle anderen Funktionen von sys für mich nutzlos sind.
Meine Fragen sind es also. Macht die erste Methode das Skript wirklich schnell? Welche Methode wird am meisten bevorzugt? Warum?
Kommentare
- Siehe auch stackoverflow.com/q/710551/321973
- Zugehöriger Beitrag – Begründung für die
from … import …
-Syntax in Python
Antwort
Beim Importieren des Moduls wird nichts verschwendet. Das Modul ist immer vollständig importiert (in die Zuordnung sys.modules
), ob Sie also import sys
oder from sys import argv
macht keine Chancen.
Der einzige Unterschied zwischen den beiden Anweisungen besteht darin, welcher Name gebunden ist; import sys
bindet den Namen sys
an das Modul (also sys
-> sys.modules["sys"]
), während from sys import argv
bindet Ein anderer Name, argv
, der direkt auf das im Modul enthaltene Attribut zeigt (also argv
-> ). Der Rest von th Das Modul sys
ist noch vorhanden, unabhängig davon, ob Sie etwas anderes aus dem Modul verwenden oder nicht.
Es gibt auch keinen Leistungsunterschied zwischen den beiden Ansätzen. Ja, sys.argv
muss zwei Dinge nachschlagen. Es muss sys
in Ihrem globalen Namespace nachschlagen (findet das Modul) und dann das Attribut argv
nachschlagen. Und ja, mit from sys import argv
können Sie die Attributsuche überspringen, da Sie bereits einen direkten Verweis auf das Attribut haben. Die Anweisung import
muss diese Aufgabe jedoch noch ausführen. Beim Importieren wird dasselbe Attribut nachgeschlagen, und Sie müssen immer nur argv
einmal . Wenn Sie argv
tausende Male in einer Schleife verwenden müssten, könnte dies möglicherweise einen Unterschied bewirken, in diesem speziellen Fall jedoch nicht
Die Wahl zwischen dem einen oder dem anderen sollte stattdessen auf dem Codierungsstil basieren.
In einem großen Modul Ich würde auf jeden Fall import sys
verwenden. Die Codedokumentation ist wichtig, und die Verwendung von sys.argv
irgendwo in einem großen Modul macht viel klarer, worauf Sie sich beziehen, als es nur argv
jemals tun würde.
Wenn der einzige Ort, an dem Sie argv
verwenden, in einem "__main__"
-Block liegt, um einen Funktion, verwenden Sie auf jeden Fall from sys import argv
, wenn Sie sich darüber glücklicher fühlen:
if __name__ == "__main__": from sys import argv main(argv)
I. „Ich benutze dort immer noch import sys
. Alle Dinge sind gleich (und sie sind genau in Bezug auf die Leistung und Anzahl der Zeichen, die zum Schreiben verwendet wurden). , das ist für mich nur augenschonender.
Wenn Sie insgesamt etwas anderes importieren, kommt möglicherweise die Leistung ins Spiel. Aber nur, wenn Sie einen bestimmten Namen in a verwenden Modul um ein Vielfaches , zum Beispiel in einer kritischen Schleife. Dann wird das Erstellen eines lokalen Namens (innerhalb einer Funktion) noch schneller:
import somemodule def somefunction(): localname = somemodule.somefunctionorother while test: # huge, critical loop foo = localname(bar)
Kommentare
- Es gibt auch Situationen, in denen Sie ein Paket mit Unterpaketen oder Modulen haben, das ein Attribut eines dieser Unterpakete / Module im Paket der obersten Ebene verfügbar macht. Mit
from...import
können Siepackage.attribute
anstelle vonpackage.subpackage_or_module.attribute
ausführen. Dies kann hilfreich sein, wenn Sie dies tun Sie haben logische oder konzeptionelle Gruppierungen innerhalb des Pakets, möchten die Benutzer des Pakets jedoch ein wenig komfortabler machen. (numpy
macht so etwas, glaube ich.) - In Django gibt es unzählige Stellen, an denen Dinge wie
from django.core.management.base import BaseCommand
sind besser und alles andere (insbesondereimport django
) würde zu unlesbarem Code führen. Obwohl mir diese Antwort gefällt, denke ich, dass es einige Bibliotheken (und insbesondere einige Frameworks) gibt, in denen die Konvention den bloßen Import verletzen soll.Verwenden Sie wie immer Ihr Urteil darüber, was in einer bestimmten Situation am besten ist. Aber irre auf der Seite von explizit (mit anderen Worten, ich stimme größtenteils zu). - @JAB: Sie können immer noch
import ... as
verwenden, um das Paket zu finden ein anderer Name:import package.subpackage_or_module as shortname
.from parent import sub
macht im Wesentlichen dasselbe. -
so wether you use import sys or from sys import argv makes no odds
Dies scheint bei IDLE nicht der Fall zu sein. Nur das Modul zu importieren, importiert seine Funktionen nicht und ich kann es in der IDLE-Shell nur von < Modul > aufrufen. < Funktion > Name - @Suncatcher: Lesen Sie meine Antwort vollständig. Der Satz, den Sie zitieren, gibt an, wie viel importiert wird und nicht, welcher Name gebunden ist. Das ‚ wird an anderer Stelle in der Antwort behandelt.
Antwort
Es gibt zwei Gründe für die Verwendung von import module
anstelle von from module import function
.
Erstens ist der Namespace. Beim Importieren einer Funktion in den globalen Namespace besteht die Gefahr von Namenskollisionen.
Zweitens ist dies nicht relevant für Standardmodule, aber für Ihre eigenen Module von Bedeutung, insbesondere während der Entwicklung. Es ist die Option, reload()
ein Modul. Beachten Sie Folgendes:
from module import func ... reload(module) # func still points to the old code
Andererseits
import module ... reload(module) # module.func points to the new code
Bezüglich der Geschwindigkeit.
Wir importieren nur die Funktion, die benötigt wird, anstatt das gesamte Modul zu importieren (das mehr nutzlose Funktionen enthält, die Python beim Importieren verschwenden wird)
Unabhängig davon, ob Sie ein Modul importieren oder eine Funktion aus einem Modul importieren, analysiert Python das gesamte Modul. In beiden Fällen wird das Modul importiert. „Importieren einer Funktion“ ist nichts anderes als das Binden der Funktion an einen Namen. Tatsächlich ist import module
für den Dolmetscher weniger Arbeit als from module import func
.
Kommentare
- reload () war in Python 2 integriert; Dies ist bei Python 3 nicht mehr der Fall.
- Ich dachte, es gibt auch Auswirkungen auf zirkuläre Importabhängigkeiten?
Antwort
Ich verwende from import
s, wenn dies die Lesbarkeit verbessert. Zum Beispiel bevorzuge ich (Semikolons sollen hier nur Platz sparen):
from collections import defaultdict from foomodule import FooBar, FooBaz from twisted.internet.protocol import Factory defaultdict(); FooBar(); FooBaz(); Factory()
anstelle von:
import collections import foomodule import twisted.internet.protocol collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz() twisted.internet.protocol.Factory()
Letzteres ist für mich schwieriger zu lesen (und zu schreiben), weil es so viele redundante Informationen enthält. Außerdem ist es nützlich, im Voraus zu wissen, welche Teile eines Moduls ich verwende.
Ich bevorzuge reguläre import
s, wenn ich Lose verwende von Kurznamen aus einem Modul:
import sys sys.argv; sys.stderr; sys.exit()
Oder wenn ein Name so allgemein ist, dass er außerhalb seines Namespace keinen Sinn ergibt:
import json json.loads(foo) from json import loads loads(foo) # potentially confusing
Kommentare
- Dies ist meine Lieblingsantwort. ‚ Explizit ist besser als implizit ‚ widerspricht manchmal der Lesbarkeit, Einfachheit und Trockenheit. Besonders wenn Sie ein Framework wie Django verwenden.
Antwort
Meiner Meinung nach mit regulärem import
verbessert die Lesbarkeit. Wenn ich Python-Code überprüfe, sehe ich gerne, woher die angegebene Funktion oder Klasse kommt, wo sie verwendet wird. Es erspart mir das Scrollen zum Anfang des Moduls, um diese Informationen zu erhalten.
Für die langen Modulnamen verwende ich einfach das Schlüsselwort as
und gebe sie kurz Aliase:
import collections as col import foomodule as foo import twisted.internet.protocol as twip my_dict = col.defaultdict() foo.FooBar() twip_fac = twip.Factory()
Ausnahmsweise verwende ich immer die Notation from module import something
, wenn ich mich mit der __future__
. Sie können es einfach nicht anders machen, wenn alle Zeichenfolgen in Python 2 standardmäßig Unicode sein sollen, z. B.
from __future__ import unicode_literals from __future__ import print_function
Kommentare
- Amen! “ importieren als “ ist eine gewinnbringende Kombination 🙂
Antwort
Obwohl import sys
und from sys import agrv
beide importieren das gesamte sys
-Modul, letzteres verwendet die Namensbindung, sodass nur das argv
-Modul für den Rest des Codes zugänglich ist.
Für einige Leute wäre dies der bevorzugte Stil, da er nur die von Ihnen explizit angegebene Funktion zugänglich macht.
Es führt jedoch zu potenziellen Namenskonflikten. Was wäre, wenn Sie ein anderes Modul mit dem Namen argv
? Beachten Sie, dass Sie die Funktion auch explizit importieren und mit from sys import argv as sys_argv
umbenennen können. Diese Konvention erfüllt den expliziten Import und gibt weniger wahrscheinlich Namensraum Kollisionen.
Kommentare
- Wie ist
if sys_argv:
besser alsif sys.argv:
? Ich weiß, was die zweite Aussage bedeutet, ich habe keine Ahnung, was die erste Form bedeutet, ohne zum bizarren Import zurückzukehren.
Antwort
Ich habe mir diese Frage kürzlich gestellt. Ich habe die verschiedenen Methoden zeitlich festgelegt.
fordert Bibliothek an
def r(): import requests return "hello" timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop def rg(): from requests import get return "hello" timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop
schöne Suppenbibliothek
def bs(): import bs4 return "hello" timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop def be(): from bs4 import BeautifulSoup return "hello" timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop
json library
def js(): import json return "hello" timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop def jl(): from json import loads return "hello" timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop
sys library
def s(): import sys return "hello" timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop def ar(): from sys import argv return "hello" timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop
Es scheint mir, dass es einen kleinen Leistungsunterschied gibt.
Kommentare
- Sie fügen eine Attributsuche hinzu. Um
import module
mitfrom module import name
korrekt zu vergleichen, fügen Sie diese Namenssuche zurimport module
Fall. Z.B. Fügen Sie die Zeilesys.argv
zumar
-Test usw. hinzu. Es wird immer noch einen Unterschied geben, da die geleistete Arbeit geringfügigunterschiedlich, da unterschiedliche Bytecodes generiert und unterschiedliche Codepfade ausgeführt werden. - Beachten Sie, dass ich diesen Unterschied in meiner Antwort direkt anspreche. Es gibt einen Unterschied zwischen der Verwendung von
import sys
und der Verwendung vonsys.argv
Tausende Male in einer Schleife undfrom sys import argv
benutze dann nurargv
. Aber Sie ‚ t. Für Dinge, die Sie nur einmal auf globaler Ebene Ihres Moduls tun, sollten Sie wirklich die Lesbarkeit optimieren, nicht mikroskopische Zeitunterschiede. - Ahhhh! Und ich dachte, ich hätte etwas vor! 🙂 Ich habe nur deine Antwort überflogen. Sieht so aus, als hätte ich die Waffe darauf gesprungen. Fühlt sich gut an, demütig zu sein.
Antwort
Veröffentlichte Codefragmente betrachten, ganze Module importieren und auf module.function
ist so ziemlich der Standard, zumindest für Standardmodule. Die einzige Ausnahme scheint datetime
from datetime import datetime, timedelta
zu sein, sodass Sie datetime.now()
statt datetime.datetime.now()
.
Wenn Sie sich Gedanken über die Leistung machen, können Sie immer (zum Beispiel)
und führen Sie dann Ihren leistungskritischen Code aus, da die Modul-Suche bereits durchgeführt wurde. Obwohl dies mit Funktionen / Methoden funktioniert, werden die meisten IDEs verwirrt und zeigen (zum Beispiel) keine Quellverknüpfung / Signatur für die Funktion an, wenn sie einer Variablen zugewiesen ist.
Antwort
Ich möchte das nur hinzufügen, wenn Sie so etwas wie
from math import sin
tun (oder eine andere integrierte Bibliothek wie sys
oder posix
), dann wird sin
in die Dokumentation für Ihr Modul aufgenommen werden (dh wenn Sie >>> help(mymodule)
oder $ pydoc3 mymodule
ausführen. Um dies zu vermeiden, importieren Sie mit:
import math from math import sin as _sin
PS: Eine integrierte Bibliothek wird aus C-Code kompiliert und in Python enthalten. argparse
, os
und io
sind keine integrierten Pakete