Maison  >  Questions et réponses  >  le corps du texte

Python, 理解下面这个装饰器(based on class), 有哪几个关键点 ?

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)
怪我咯怪我咯2741 Il y a quelques jours468

répondre à tous(2)je répondrai

  • PHP中文网

    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 :

    1. accède d'abord au __dict__ de l'objet, c'est-à-dire a.__dict__['val'] ;

    2. S'il n'y a pas de
    3. pour accéder à nouveau à la classe, elle recherchera vers le haut le long de la relation d'héritage

      A.__dict__['val'] ;

    4. Si
    5. est trouvé et qu'une valeur est renvoyée, alors la valeur est obtenue ; si un descripteur est renvoyé, la méthode

      du descripteur sera appelée A.__dict__['val']__get__ ;

    6. Pour
    ici :

    memoized_propertyPar 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,

    c'est très clair, il suffit de supprimer le chemin avec la priorité précédente. Ensuite, Python a dû rechercher étape par étape la priorité et a découvert que

    était disponible, il a donc appelé la méthode reset et l'a recalculée à nouveau. __get__ a.valEt l'intérieur de

    peut être considéré comme bien meilleur. . . .

    répondre
    0
  • PHP中文网

    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

    répondre
    0
  • Annulerrépondre