Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk melaksanakan import malas import-malas Python

Bagaimana untuk melaksanakan import malas import-malas Python

王林
王林ke hadapan
2023-04-20 11:04:061227semak imbas

Jika program Python anda mempunyai bilangan import yang banyak dan bermula dengan perlahan, maka anda harus mencuba import malas Artikel ini berkongsi kaedah untuk mencapai import malas. Walaupun PEP0690[1] telah mencadangkan untuk menambah ciri ini pada pengkompil Python (-L) atau perpustakaan standard, versi Python semasa masih belum melaksanakannya.

Seperti yang kita semua tahu, aplikasi Python akan melakukan operasi import sebelum melaksanakan operasi sebenar pengguna Modul yang berbeza mungkin datang dari lokasi yang berbeza, sesetengah modul mungkin sangat memakan masa untuk dijalankan, dan sesetengah modul mungkin tidak. berfungsi sama sekali. Ia dipanggil oleh pengguna, jadi pengimportan banyak modul adalah membuang masa.

Jadi kita memerlukan import malas Apabila import malas digunakan, menjalankan import foo hanya akan menambah nama foo ke ruang nama penuh global (globals()) sebagai rujukan malas Pengkompil Operasi import sebenar ialah tidak dilakukan sehingga sebarang kod mengakses foo ditemui. Begitu juga, dari bar import foo akan menambah bar pada ruang nama, dan apabila ia menemui kod yang memanggil bar, ia akan mengimport foo.

Tulis kod untuk melaksanakannya

Jadi bagaimana untuk menulis kod untuk melaksanakannya? Malah, tidak perlu menulis kod untuk melaksanakannya. Sudah ada projek yang melaksanakan fungsi import malas, iaitu kodnya tidak bergantung pada mana-mana perpustakaan pihak ketiga. apabila anda memerlukan import malas, anda boleh terus meletakkan kelas LazyLoader[2] Hanya salin ke projek anda sendiri.

Kod sumber adalah seperti berikut:

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

Perihalan kod:

Kelas LazyLoader mewarisi daripada jenis.ModuleType dan fungsi permulaan memastikan bahawa modul malas akan berkelakuan seperti sebenar Modul juga ditambah dengan betul pada pembolehubah global Hanya apabila modul benar-benar digunakan, iaitu, apabila __getattr__ atau __dir__ dilaksanakan, modul sebenar akan benar-benar diimport, pembolehubah global. akan dikemas kini untuk menunjuk ke modul sebenar, dan semua statusnya ( __dict__) dikemas kini kepada keadaan modul sebenar supaya rujukan kepada pemuatan malas, memuatkan modul tidak perlu melalui proses pemuatan setiap kali ia diakses .

Penggunaan kod:

Biasanya kami mengimport modul seperti ini:

import tensorflow.contrib as contrib

Versi import malas yang sepadan adalah seperti berikut:

contrib = LazyLoader('contrib', globals(), 'tensorflow.contrib')

Pendekatan disyorkan PEP0690

Cadangan PEP0690 adalah untuk melaksanakannya di peringkat pengkompil (kod C), supaya prestasinya menjadi lebih baik. Terdapat dua cara untuk menggunakannya.

Satu cara

Salah satu cara ialah menambah parameter -L apabila melaksanakan skrip Python Contohnya, terdapat dua fail spam.py dengan kandungan berikut:

import time
time.sleep(10)
print("spam loaded")

kandungan egg.py adalah seperti berikut:

import spam
print("imports done")

Di bawah keadaan import biasa, ia akan menunggu selama 10 saat sebelum mencetak "spam dimuatkan" dan kemudian "import selesai", apabila melaksanakan python -L eggs.py , modul spam tidak pernah diimport dan modul spam yang digunakan tidak digunakan sama sekali. Jika kandungan egg.py adalah seperti berikut:

import spam
print("imports done")
spam

Apabila python -L eggs.py dilaksanakan, "import selesai" akan dicetak dahulu dan "spam dimuatkan" akan dicetak 10 saat kemudian).

Kedua

Cara lain ialah memanggil kaedah importlib perpustakaan standard:

import importlib 
importlib.set_lazy_imports(True)

Jika sesuatu Modul tidak boleh malas dimuatkan dan perlu dikecualikan Anda boleh melakukannya seperti ini:

import importlib 
importlib.set_lazy_imports(True,excluding=["one.mod", "another"])

Anda juga boleh melakukannya seperti ini:

from importlib import eager_imports

with eager_imports():
import foo
import bar

Perkataan akhir

Selepas ujian oleh profesional pada program baris arahan Python sebenar, menggunakan import malas boleh meningkatkan masa permulaan sebanyak 70% dan mengurangkan penggunaan memori sebanyak 40%, yang sangat mengagumkan.

Rujukan

[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

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan import malas import-malas Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam