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.
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')
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
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.
[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!