Pertimbangkan yang berikut ini:
@property
def name(self):
if not hasattr(self, '_name'):
# expensive calculation
self._name = 1 + 1
return self._name
Saya baru, tapi saya pikir caching bisa diperhitungkan menjadi dekorator. Hanya saya tidak menemukan yang seperti itu;)
PS perhitungan sebenarnya tidak tergantung pada nilai yang bisa diubah
python
caching
decorator
memoization
Tobias
sumber
sumber
Jawaban:
Mulai dari Python 3.2 ada dekorator bawaan:
@functools.lru_cache(maxsize=100, typed=False)
Contoh cache LRU untuk menghitung angka Fibonacci :
Jika Anda terjebak dengan Python 2.x, berikut adalah daftar pustaka memoisasi lain yang kompatibel:
functools32
| PyPI | Kode sumberrepoze.lru
| PyPI | Kode sumberpylru
| PyPI | Kode sumberbackports.functools_lru_cache
| PyPI | Kode sumbersumber
lru_cache
membuat salinan dari hasil apa pun yang di-cache, dan tidak ada salinan yang dibuat dalamfunctools.lru_cache
implementasinya. Melakukannya juga akan berisiko menciptakan masalah memori yang sulit ditemukan ketika digunakan untuk men-cache objek besar.Sepertinya Anda tidak meminta dekorator memoisasi tujuan umum (mis. Anda tidak tertarik pada kasus umum di mana Anda ingin menyimpan nilai pengembalian cache untuk nilai argumen yang berbeda). Yaitu, Anda ingin memiliki ini:
sementara dekorator memoisasi keperluan umum akan memberi Anda ini:
Saya sampaikan bahwa sintaks pemanggilan metode adalah gaya yang lebih baik, karena ini menyarankan kemungkinan perhitungan yang mahal sementara sintaksis properti menyarankan pencarian cepat.
[Pembaruan: Dekorator memoisasi berbasis kelas yang saya tautkan dan kutip di sini sebelumnya tidak berfungsi untuk metode. Saya telah menggantinya dengan fungsi dekorator.] Jika Anda ingin menggunakan dekorator memoisasi tujuan umum, berikut ini sederhana:
Contoh penggunaan:
Dekorator memoisasi lain dengan batasan ukuran cache dapat ditemukan di sini .
sumber
fibonacci
. Fungsi itu selalu menggunakanmemo
kamus yang sama .Sampel menggunakan:
sumber
functools.cached_property
Dekorator Python 3.8https://docs.python.org/dev/library/functools.html#functools.cached_property
cached_property
dari Werkzeug disebutkan di: https://stackoverflow.com/a/5295190/895245 tetapi versi yang seharusnya diturunkan akan digabung menjadi 3,8, yang luar biasa.Penghias ini dapat dilihat sebagai caching
@property
, atau sebagai pembersih@functools.lru_cache
ketika Anda tidak memiliki argumen.Dokumen mengatakan:
sumber
Werkzeug memiliki
cached_property
dekorator ( dokumen , sumber )sumber
Saya mengkodekan kelas dekorator sederhana ini untuk menyimpan respons fungsi cache. Saya merasa ini SANGAT berguna untuk proyek saya:
Penggunaannya sangat mudah:
sumber
@cached
kurung pertama Anda tidak ada. Lain itu hanya akan mengembalikancached
objek di tempatmyfunc
dan ketika dipanggil sepertimyfunc()
ituinner
akan selalu dikembalikan sebagai nilai kembaliDISCLAIMER: Saya penulis kids.cache .
Anda harus memeriksa
kids.cache
, ia menyediakan@cache
dekorator yang bekerja pada python 2 dan python 3. Tidak ada ketergantungan, ~ 100 baris kode. Sangat mudah digunakan, misalnya, dengan mengingat kode Anda, Anda dapat menggunakannya seperti ini:Kemudian
Atau Anda bisa meletakkan
@cache
dekorator setelah@property
(hasil yang sama).Menggunakan cache pada properti disebut evaluasi malas ,
kids.cache
dapat melakukan lebih banyak lagi (ini berfungsi dengan argumen, properti, semua jenis metode, dan bahkan kelas ...). Untuk pengguna tingkat lanjut,kids.cache
dukungancachetools
yang menyediakan toko cache mewah ke python 2 dan python 3 (LRU, LFU, TTL, cache RR).CATATAN PENTING : penyimpanan cache default
kids.cache
adalah dict standar, yang tidak disarankan untuk program yang berjalan lama dengan kueri yang berbeda karena akan mengarah pada penyimpanan cache yang terus berkembang. Untuk penggunaan ini, Anda dapat memasang plugin toko cache lain menggunakan misalnya (@cache(use=cachetools.LRUCache(maxsize=2))
untuk menghias fungsi / properti / kelas / metode ...)sumber
c
dariMyClass
, dan memeriksanya denganobjgraph.show_backrefs([c], max_depth=10)
, ada rantai referensi dari objek kelasMyClass
kec
. Artinya,c
tidak akan pernah dirilis sampaiMyClass
dirilis.Ah, hanya perlu menemukan nama yang tepat untuk ini: " Evaluasi properti malas ".
Saya juga banyak melakukan ini; mungkin saya akan menggunakan resep itu dalam kode saya kapan-kapan.
sumber
Ada fastcache , yang merupakan "implementasi C dari Python 3 functools.lru_cache. Menyediakan speedup 10-30x lebih dari perpustakaan standar."
Sama seperti jawaban yang dipilih , hanya impor yang berbeda:
Juga, ia dipasang di Anaconda , tidak seperti functools yang perlu diinstal .
sumber
functools
adalah bagian dari pustaka standar, tautan yang Anda poskan adalah garpu git acak atau yang lainnya ...Ada contoh lain dari dekorator memoize di Python Wiki:
http://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
Contoh itu agak cerdas, karena tidak akan men-cache hasil jika parameternya bisa berubah. (periksa kode itu, sangat sederhana dan menarik!)
sumber
Jika Anda menggunakan Django Framework, ia memiliki properti seperti itu untuk men-cache tampilan atau respons penggunaan API
@cache_page(time)
dan mungkin ada opsi lain juga.Contoh:
Rincian lebih lanjut dapat ditemukan di sini .
sumber
Bersama dengan Contoh Memoize saya menemukan paket python berikut:
sumber
Saya menerapkan sesuatu seperti ini, menggunakan acar untuk ketekunan dan menggunakan sha1 untuk ID pendek yang hampir pasti-unik. Pada dasarnya cache hash kode fungsi dan hist argumen untuk mendapatkan sha1 kemudian mencari file dengan sha1 di namanya. Jika ada, itu akan membukanya dan mengembalikan hasilnya; jika tidak, ia memanggil fungsi dan menyimpan hasilnya (opsional hanya menyimpan jika butuh waktu untuk diproses).
Yang mengatakan, saya bersumpah saya menemukan modul yang ada yang melakukan ini dan menemukan diri saya di sini mencoba menemukan modul itu ... Yang paling dekat saya dapat temukan adalah ini, yang terlihat benar: http: //chase-seibert.github. io / blog / 2011/11/23 / pythondjango-disk-caching-decorator.html
Satu-satunya masalah yang saya lihat adalah itu tidak akan bekerja dengan baik untuk input besar karena memiliki str (arg), yang tidak unik untuk array raksasa.
Akan lebih baik jika ada protokol unique_hash () yang memiliki kelas mengembalikan hash aman dari isinya. Saya pada dasarnya menerapkannya secara manual untuk jenis yang saya pedulikan.
sumber
Coba joblib http://pythonhosted.org/joblib/memory.html
sumber
Jika Anda menggunakan Django dan ingin men-cache view, lihat jawaban Nikhil Kumar .
Tetapi jika Anda ingin men-cache hasil fungsi APAPUN, Anda dapat menggunakan django-cache-utils .
Menggunakan kembali cache Django dan menyediakan
cached
dekorator yang mudah digunakan :sumber
@lru_cache
tidak sempurna dengan nilai fungsi defaultmem
dekorator saya :dan kode untuk pengujian:
hasil - hanya 3 kali dengan tidur
tetapi dengan
@lru_cache
itu akan menjadi 4 kali, karena ini:akan dihitung dua kali (kerja buruk dengan default)
sumber