it-swarm.com.de

'Modul importieren' vs. 'aus Modulimportfunktion'

Ich habe immer diese Methode verwendet:

from sys import argv

und benutze argv mit nur argv. Es gibt jedoch eine Konvention, dies zu verwenden:

import sys

und mit dem argv 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 Funktion importieren, die benötigt wird, anstatt das gesamte Modul zu importieren (das mehr nutzlose Funktionen enthält, die python wird Zeit damit verschwenden, sie zu importieren). Beachten Sie, dass ich nur argv brauche und alle anderen Funktionen von sys für mich nutzlos sind.

Meine Fragen sind also. Macht die erste Methode das Skript wirklich schnell? Welche Methode wird am meisten bevorzugt? Warum?

157
Santosh Kumar

Das Importieren des Moduls verschwendet nicht irgendetwas; Das Modul wird immer vollständig importiert (in das Mapping sys.modules). Ob Sie also import sys oder from sys import argv verwenden, macht keine Chancen.

Der einzige Unterschied zwischen den beiden Aussagen 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 Einen anderen Namen bindet, argv und zeigt direkt auf das im Modul enthaltene Attribut (also argv -> sys.modules['sys'].argv). Der Rest des Moduls 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 argveinmal verwenden. 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 anderen sollte dann stattdessen auf Codierungsstil basieren.

In einem großen Modul würde ich sicherlich 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 eine main() - Funktion aufzurufen, 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)

Ich würde dort immer noch import sys Verwenden. Wenn alle Dinge gleich sind (und genau in Bezug auf die Leistung nd Anzahl der Zeichen, die zum Schreiben verwendet wurden), ist das für mich nur einfacher.

Wenn Sie etwas importieren else insgesamt, dann kommt vielleicht die Leistung ins Spiel. Aber nur, wenn Sie einen bestimmten Namen in einem Modul verwenden m ein Vielfaches, zum Beispiel in einer kritischen Schleife. Aber dann wird das Erstellen eines lokalen Namens (innerhalb einer Funktion) noch schneller gehen:

 import somemodule

 def somefunction():
      localname = somemodule.somefunctionorother
      while test:
          # huge, critical loop
          foo = localname(bar)
184
Martijn Pieters

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 für Standardmodule nicht relevant, aber für Ihre eigenen Module von Bedeutung, insbesondere während der Entwicklung. Es ist die Option, ein Modul zu reload(). Bedenken Sie:

from module import func
...
reload(module)
# func still points to the old code

Auf der anderen Seite

import module
...
reload(module)
# module.func points to the new code

Was die Geschwindigkeit betrifft ...

wir importieren nur die Funktion, die benötigt wird, anstatt das gesamte Modul zu importieren (das mehr nutzlose Funktionen enthält, die python wird Zeit damit verschwenden, sie zu importieren).

Unabhängig davon, ob Sie ein Modul importieren oder eine Funktion aus einem Modul importieren, Python analysiert das gesamte Modul. In beiden Fällen wird das Modul importiert. "Importieren einer Funktion" ist nichts anderes als das Binden der Funktion an a Tatsächlich ist import module für Dolmetscher weniger Arbeit als from module import func.

47
vartec

Meiner Meinung nach verbessert die Verwendung von normalem import die Lesbarkeit. Beim Überprüfen von Python Code möchte ich sehen, woher die angegebene Funktion oder Klasse kommt, genau dort, wo sie verwendet wird. Es erspart mir das Scrollen zum oberen Rand des Moduls, um diese Informationen zu erhalten.

Für die langen Modulnamen verwende ich einfach das Schlüsselwort as und gebe ihnen kurze 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 from module import something - Notation, wenn ich mich mit dem __future__ - Modul befasse. Sie können es einfach nicht anders machen, wenn alle Zeichenfolgen standardmäßig in Python 2, z.

from __future__ import unicode_literals
from __future__ import print_function
19
golem

Ich benutze from imports wann immer es 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()

anstatt:

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 hilfreich, im Voraus zu wissen, welche Teile eines Moduls ich verwende.

Ich bevorzuge reguläre imports, wenn ich viele Kurznamen aus einem Modul verwende:

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
19
user76704

Obwohl import sys Und from sys import agrv Beide das gesamte sys -Modul importieren, verwendet letzteres 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 namens argv hätten? 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 führt mit geringerer Wahrscheinlichkeit zu Namensraumkollisionen.

4
Duncan

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 Suppe Bibliothek

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-Bibliothek

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 Bibliothek

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 gibt einen kleinen Unterschied in der Leistung.

1
tmthyjames