栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用类作为方法装饰器

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用类作为方法装饰器

通常,当方法访问为时

some_instance.some_method()
,python的描述符协议会加入并调用
some_method.__get__()
,这会返回绑定的方法。但是,由于该方法已被
Deco
类的实例替换,因此不会发生-
因为
Deco
它不是描述符。为了
Deco
按预期进行工作,它必须实现一个
__get__
返回自身绑定副本的方法。

实作

这是基本的“不执行任何操作”修饰符类:

import inspectimport functoolsfrom copy import copyclass Deco(object):    def __init__(self, func):        self.__self__ = None # "__self__" is also used by bound methods        self.__wrapped__ = func        functools.update_wrapper(self, func)    def __call__(self, *args, **kwargs):        # if bound to an object, pass it as the first argument        if self.__self__ is not None: args = (self.__self__,) + args        #== change the following line to make the decorator do something ==        return self.__wrapped__(*args, **kwargs)    def __get__(self, instance, owner):        if instance is None: return self        # create a bound copy        bound = copy(self)        bound.__self__ = instance        # update __doc__ and similar attributes        functools.update_wrapper(bound, self.__wrapped__)        # add the bound instance to the object's dict so that        # __get__ won't be called a 2nd time        setattr(instance, self.__wrapped__.__name__, bound)        return bound

要使装饰器执行某些操作,请在

__call__
方法中添加代码。


这是一个带有参数的参数:

class DecoWithArgs(object):    #== change the constructor's parameters to fit your needs ==    def __init__(self, *args):        self.args = args        self.__wrapped__ = None        self.__self__ = None    def __call__(self, *args, **kwargs):        if self.__wrapped__ is None: return self.__wrap(*args, **kwargs)        else: return self.__call_wrapped_function(*args, **kwargs)    def __wrap(self, func):        # update __doc__ and similar attributes        functools.update_wrapper(self, func)        return self    def __call_wrapped_function(self, *args, **kwargs):        # if bound to an object, pass it as the first argument        if self.__self__ is not None: args = (self.__self__,) + args        #== change the following line to make the decorator do something ==        return self.__wrapped__(*args, **kwargs)    def __get__(self, instance, owner):        if instance is None: return self        # create a bound copy of this object        bound = copy(self)        bound.__self__ = instance        bound.__wrap(self.__wrapped__)        # add the bound decorator to the object's dict so that        # __get__ won't be called a 2nd time        setattr(instance, self.__wrapped__.__name__, bound)        return bound

这样的实现使我们可以在方法和函数上使用装饰器,因此我认为应该将其视为良好实践。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/669124.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号