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

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 Sie package.attribute anstelle von package.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 (insbesondere import 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 als if 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 mit from module import name korrekt zu vergleichen, fügen Sie diese Namenssuche zur import module Fall. Z.B. Fügen Sie die Zeile sys.argv zum ar -Test usw. hinzu. Es wird immer noch einen Unterschied geben, da die geleistete Arbeit geringfügig unterschiedlich, 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 von sys.argv Tausende Male in einer Schleife und from sys import argv benutze dann nur argv. 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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.