您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python装饰器,自我混淆

Python装饰器,自我混淆

像这样使用描述符协议

import functools

class cacher(object):

    def __init__(self, f):
        self.f = f
        self.cache = {}

    def __call__(self, *args):
        fname = self.f.__name__
        if (fname not in self.cache):
            self.cache[fname] = self.f(self,*args)
        else:
            print "using cache"
        return self.cache[fname]

    def __get__(self, instance, instancetype):
        """Implement the descriptor protocol to make decorating instance 
        method possible.

        """

        # Return a partial function with the first argument is the instance 
        #   of the class decorated.
        return functools.partial(self.__call__, instance)

在装饰器中使用描述符协议将使我们能够以正确的实例作为自身来访问装饰的方法,也许一些代码可以提供更好的帮助:

现在,当我们要做的时候:

class Session(p.Session):
    ...

    @cacher
    def get_something(self):
        print "get_something called with self = %s "% self
        return self.pl.get_something()

相当于:

class Session(p.Session):
    ...

    def get_something(self):
        print "get_something called with self = %s "% self
        return self.pl.get_something()

    get_something = cacher(get_something)

因此,现在get_something是cacher的实例。因此,当我们调用方法get_something时,它将被转换为此(由于描述符协议):

session = Session()
session.get_something  
#  <==> 
session.get_something.__get__(get_something, session, <type ..>)
# N.B: get_something is an instance of cacher class.

并且因为:

session.get_something.__get__(get_something, session, <type ..>)
# return
get_something.__call__(session, ...) # the partial function.

所以

session.get_something(*args)
# <==>
get_something.__call__(session, *args)

希望这会解释它是如何工作的:)

python 2022/1/1 18:31:57 有500人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶