Maison > Questions et réponses > le corps du texte
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
Selon la méthode d'implémentation de memoized_property, les réponses suivantes ont toutes une prémisse, c'est-à-dire qu'il est supposé qu'elle est utilisée comme décorateur pour les fonctions de classe. À ce stade, cette classe peut être considérée comme une version modifiée du décorateur de propriétés. L'effet de mise en cache peut être obtenu car Python a la priorité lors de l'accès aux attributs .
Pour a.val
, Python effectue le traitement suivant :
accède d'abord au __dict__
de l'objet, c'est-à-dire a.__dict__['val']
;
A.__dict__['val']
;
du descripteur sera appelée A.__dict__['val']
__get__
;
memoized_property
Par exemple, cette classe encapsule la fonction val de la classe A :
class A(object):
...
@memoized_property
def val(self):
...
a = A()
a.val
Lors du premier accès à
, selon la séquence de recherche ci-dessus : il n'est pas trouvé dans l'objet, passez à la deuxième étape, il est trouvé dans le dictionnaire de classe, mais il s'agit d'un descripteur ; , il entrera donc le descripteur dans la méthode. Ici, après avoir utilisé val
pour appeler la fonction décorée __get__
et calculer le résultat, tout en renvoyant le résultat, le résultat est également stocké dans self.fget(obj)
. La prochaine fois que vous visiterez val
, puisque le obj.__dict__['val']
de l'objet contient a.val
, il recherchera __dict__
d'abord au lieu de tout mettre en œuvre pour trouver val
. Cela permet d'obtenir l'effet de mettre en cache un attribut. Le général obj.__dict__['val']
ne réglera pas __get__
, il sera donc recalculé à chaque fois. __get__
obj.__dict__['xxx']
Après avoir compris cela,
était disponible, il a donc appelé la méthode reset
et l'a recalculée à nouveau. __get__
a.val
Et l'intérieur de
PHP中文网2017-04-18 10:35:42
Une méthode de classe est une méthode que vous pouvez appeler directement sans instancier la classe