Heim  >  Artikel  >  Backend-Entwicklung  >  So implementieren Sie Pythons Lazy Import-Lazy Import

So implementieren Sie Pythons Lazy Import-Lazy Import

王林
王林nach vorne
2023-04-20 11:04:061231Durchsuche

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.

Schreiben Sie Code, um ihn zu implementieren

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')

PEP0690 Der empfohlene Ansatz

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

Abschlussworte

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.

Referenzen

[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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:51cto.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen