Ini adalah bagaimana Anda dapat memo fungsi Python:
def memo_square(a, cache={}): if a not in cache: cache[a] = a*a return cache[a]
Penerimaan tidak diketahui sedikit pun, jadi di bawah potongan, kami akan menganalisis cara kerjanya dan untuk apa.
Pertama, bagaimana dan mengapa itu berhasil.
memo_square
(seperti fungsi lainnya) adalah objek dari kelas fungsi, yang, di antara atribut lainnya, memiliki
memo_square.__defaults__
tuple diisi saat membuat objek. Pertama, ini berisi kamus kosong, seperti yang ditunjukkan di header fungsi:
>>> memo_square.__defaults__ ({},)
__defaults__
adalah tuple biasa dan Anda tidak dapat mengubah elemen-elemennya. Benar, Anda dapat mengganti seluruh rangkaian nilai default sekaligus, tetapi hanya untuk tuple lain:
>>> def test(a=1, b=2): ... print(a, b) ... >>> test.__defaults__ (1, 2) >>> test() 1 2 >>> test.__defaults__ = (', ', '') >>> test() , >>> test.__defaults__[1] = '' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> test.__defaults__ = {0: ', ', 1: ''} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __defaults__ must be set to a tuple object
Soryan, artikel ini tidak akan sampai ke Picaba. Baiklah, ini tidak penting. Yang penting adalah bahwa dengan pengecualian kode yang sangat rumit,
func.__defaults__
dibuat sekali selama waktu program bersama dengan semua elemennya. Sebuah tuple dan elemen-elemennya tidak akan dibuat ulang dengan setiap pemanggilan fungsi, mereka akan digunakan selama fungsi itu ada. Tetapi untuk berubah, jika elemen-elemen itu sendiri bisa berubah, tidak ada yang melarangnya. Ketidakmampuan untuk bekerja dengan elemen-elemen tersebut adalah
salah satu cara paling umum untuk menembak diri sendiri dengan python . Tetapi sebenarnya menyimpan nilai di antara panggilan fungsi bisa sangat berguna. Setelah beberapa panggilan,
memo_square.__defaults__
akan terlihat seperti ini:
>>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4},) >>> memo_square(5) 25 >>> memo_square.__defaults__ ({2: 4, 5: 25},) >>> memo_square(2) 4 >>> memo_square.__defaults__ ({2: 4, 5: 25},)
Jika fungsi telah dipanggil untuk nilai yang sama, maka nilainya dihitung dan, karenanya, cache tidak diisi ulang. Untuk kotak, manfaatnya kecil (secara tegas, untuk kotak, manfaatnya negatif, karena mencari di kamus lebih mahal daripada mengalikan dua angka), tetapi untuk fungsi yang sangat mahal, memoisasi / caching bisa berguna. Tentu saja, Anda bisa menyediakannya dengan python dalam lebih dari satu cara. Berikut adalah alternatif yang kami miliki:
Hal utama yang hilang dari metode memoisasi ini adalah tidak terlalu idiomatis. Secara pribadi, ketika saya menemukan keputusan ini untuk pertama kalinya, saya berpikir selama beberapa menit tentang apa yang terjadi di sini dan mengapa. Di sisi lain, dalam beberapa menit ini saya mulai memahami sedikit lebih baik bagaimana fungsi Python dan argumen mereka diatur. Jadi, bahkan jika Anda tidak menggunakan argumen default (untuk memoisasi atau, misalnya,
mempercepat resolusi nama ), mengetahui teknik ini masih berguna untuk ahli gizi mana pun.