Wenn Ihr Python-Programm eine große Anzahl von Importen hat und sehr langsam startet, sollten Sie einen verzögerten Import versuchen. In diesem Artikel wird eine Methode beschrieben, um einen verzögerten Import zu erreichen. Obwohl PEP0690[1] vorgeschlagen hat, dem Python-Compiler (-L) oder der Standardbibliothek das Hinzufügen dieser Funktion zu ermöglichen, ist sie in der aktuellen Python-Version noch nicht implementiert.
Wie wir alle wissen, führen Python-Anwendungen Importvorgänge aus, bevor sie die tatsächlichen Vorgänge des Benutzers ausführen. Verschiedene Module können von unterschiedlichen Standorten stammen, die Ausführung einiger Module kann sehr zeitaufwändig sein und einige Module werden möglicherweise nicht aufgerufen Daher ist der Import vieler Module Zeitverschwendung.
Wenn wir Lazy Import anwenden, wird beim Ausführen von import foo nur der Name foo als Lazy-Referenz zum globalen vollständigen Namensraum hinzugefügt. Der eigentliche Importvorgang wird ausgeführt nur im Code von foo. In ähnlicher Weise fügt from foo import bar bar zum Namespace hinzu, und wenn es auf Code stößt, der bar aufruft, wird foo importiert.
Wie schreibt man also Code, um ihn zu implementieren? Tatsächlich ist es nicht erforderlich, Code zu schreiben, um die Lazy-Import-Funktion zu implementieren. Das heißt, der Code von TensorFlow ist hier nicht mehr erforderlich. Wenn Sie einen verzögerten Import benötigen, können Sie die Klasse LazyLoader[2] direkt einfügen. Kopieren Sie sie einfach in Ihr eigenes Projekt.
Der Quellcode lautet wie folgt:
# Code copied from https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/util/lazy_loader.py """A LazyLoader class.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import importlib import types class LazyLoader(types.ModuleType): """Lazily import a module, mainly to avoid pulling in large dependencies. `contrib`, and `ffmpeg` are examples of modules that are large and not always needed, and this allows them to only be loaded when they are used. """ # The lint error here is incorrect. def __init__(self, local_name, parent_module_globals, name):# pylint: disable=super-on-old-class self._local_name = local_name self._parent_module_globals = parent_module_globals super(LazyLoader, self).__init__(name) def _load(self): # Import the target module and insert it into the parent's namespace module = importlib.import_module(self.__name__) self._parent_module_globals[self._local_name] = module # Update this object's dict so that if someone keeps a reference to the # LazyLoader, lookups are efficient (__getattr__ is only called on lookups # that fail). self.__dict__.update(module.__dict__) return module def __getattr__(self, item): module = self._load() return getattr(module, item) def __dir__(self): module = self._load() return dir(module)
Codebeschreibung:
Die Klasse LazyLoader erbt von „types.ModuleType“. Die Initialisierungsfunktion stellt sicher, dass das Lazy-Modul wie ein echtes Modul korrekt zur globalen Variablen hinzugefügt wird Das heißt, wenn __getattr__ oder __dir__ ausgeführt wird, wird das tatsächliche Modul tatsächlich importiert, die globale Variable wird aktualisiert, um auf das tatsächliche Modul zu verweisen, und alle ihre Status (__dict__) werden auf den Status aktualisiert des tatsächlichen Moduls, um auf das verzögerte Laden zu verweisen und das Modul zu laden. Es ist nicht erforderlich, den Ladevorgang bei jedem Besuch durchzuführen.
Codeverwendung:
Normalerweise importieren wir das Modul wie folgt:
import tensorflow.contrib as contrib
Die entsprechende Lazy-Import-Version lautet wie folgt:
contrib = LazyLoader('contrib', globals(), 'tensorflow.contrib')
PEP0690s Vorschlag besteht darin, es im Compiler zu kompilieren ( Implementierung der C-Code-Ebene, sodass die Leistung besser ist. Es gibt zwei Möglichkeiten, es zu verwenden.
Eine Möglichkeit
Eine Möglichkeit besteht darin, beim Ausführen des Python-Skripts den Parameter -L hinzuzufügen. Beispielsweise gibt es zwei Dateien spam.py mit folgendem Inhalt:
import time time.sleep(10) print("spam loaded")
egg.py mit folgendem Inhalt :
import spam print("imports done")
Normaler Import In diesem Fall wird nach 10 Sekunden zuerst „Spam geladen“ und dann „Importe fertig“ gedruckt. Beim Ausführen von python -L egg.py wird das Spam-Modul nie importiert , und das verwendete Spam-Modul wird überhaupt nicht verwendet. Wenn der Inhalt von egg.py wie folgt lautet:
import spam print("imports done") spam
Wenn python -L egg.py ausgeführt wird, wird zuerst „Importe erledigt“ und 10 Sekunden später „Spam geladen“ gedruckt.
Zweitens
Eine andere Möglichkeit besteht darin, die Importlib-Methode der Standardbibliothek aufzurufen:
import importlib importlib.set_lazy_imports(True)
Wenn einige Module nicht verzögert geladen werden können und ausgeschlossen werden müssen, können Sie dies tun
import importlib importlib.set_lazy_imports(True,excluding=["one.mod", "another"])
Sie können dies auch tun :
from importlib import eager_imports with eager_imports(): import foo import bar
Nach Tests durch Profis mit einem echten Python-Befehlszeilenprogramm kann die Anwendung von Lazy Import die Startzeit um 70 % verlängern und die Speichernutzung um 40 % reduzieren, was sehr beeindruckend ist.
[1]PEP0690: https://github.com/python/peps/blob/main/pep-0690.rst
[2]LazyLoader: https://github.com/tensorflow/tensorflow / blob/master/tensorflow/python/util/lazy_loader.py
Das obige ist der detaillierte Inhalt vonSo implementieren Sie Pythons Lazy Import-Lazy Import. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!