Rumah > Soal Jawab > teks badan
class memoized_property(object):
"""A read-only @property that is only evaluated once."""
def __init__(self, fget, doc=None):
self.fget = fget
self.__doc__ = doc or fget.__doc__
self.__name__ = fget.__name__
# 这个方法应该是这个缓存装饰器的关键
# 因此, 我组织关键字如下
# * python __get__
# * how python __get__ works
# # python descript tools
def __get__(self, obj, cls):
if obj is None:
return self
obj.__dict__[self.__name__] = result = self.fget(obj)
return result
def _reset(self, obj):
memoized_property.reset(obj, self.__name__)
@classmethod
def reset(cls, obj, name):
obj.__dict__.pop(name, None)
PHP中文网2017-04-18 10:35:42
Menurut kaedah pelaksanaan memoized_property, jawapan berikut semuanya mempunyai premis, iaitu, diandaikan ia digunakan sebagai penghias untuk fungsi kelas. Pada ketika ini kelas ini boleh dianggap sebagai versi pengubahsuaian penghias hartanah. Kesan caching boleh dicapai kerana Python mempunyai keutamaan apabila mengakses atribut .
Untuk a.val
, Python melakukan pemprosesan berikut:
mula-mula mengakses __dict__
objek, iaitu, a.__dict__['val']
;
A.__dict__['val']
Jika
Untuk A.__dict__['val']
di sini: __get__
class A(object):
...
@memoized_property
def val(self):
...
a = A()
a.val
buat kali pertama, mengikut urutan carian di atas: ia tidak ditemui dalam objek, lompat ke langkah kedua; ia ditemui dalam kamus kelas, tetapi ia didapati sebagai deskriptor , jadi ia akan memasukkan deskriptor dalam kaedah memoized_property
. Di sini, selepas menggunakan
yang dihias dan mengira hasilnya, sambil mengembalikan hasilnya, hasilnya juga disimpan dalam
. Pada kali seterusnya anda melawat, memandangkan terdapat val
dalam __get__
objek, ia akan mencari self.fget(obj)
terlebih dahulu dan bukannya berusaha habis-habisan untuk mencari val
. Ini mencapai kesan cache atribut. obj.__dict__['val']
am tidak akan menetapkan a.val
, jadi ia akan dikira semula setiap kali. __dict__
val
Selepas memahami perkara ini, obj.__dict__['val']
ia sangat jelas, cuma alih keluar laluan dengan keutamaan sebelumnya. Kemudian Python terpaksa mencari langkah demi langkah di sepanjang keutamaan dan mendapati bahawa __get__
tersedia, jadi ia memanggil kaedah __get__
di dalamnya dan mengira semula sekali lagi. obj.__dict__['xxx']
boleh dikatakan jauh lebih baik. . . . reset
PHP中文网2017-04-18 10:35:42
Kaedah kelas ialah kaedah yang anda boleh panggil terus tanpa membuat seketika kelas