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

如何创建可以使用或不使用参数的Python装饰器?

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

如何创建可以使用或不使用参数的Python装饰器?

我知道这个问题很旧,但是有些评论是新的,尽管所有可行的解决方案本质上都是相同的,但大多数解决方案都不是很干净也不易于阅读。

就像thobe的回答所说,处理这两种情况的唯一方法是检查这两种情况。最简单的方法是简单地检查是否有单个参数并且它是callabe(注意:如果您的装饰器仅接受1个参数并且恰好是一个可调用对象,则需要额外检查):

def decorator(*args, **kwargs):    if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):        # called as @decorator    else:        # called as @decorator(*args, **kwargs)

在第一种情况下,您可以执行任何普通装饰器所执行的操作,返回传入函数的修改或包装版本。

在第二种情况下,您返回一个“新”修饰符,该修饰符以某种方式使用通过 args,* kwargs传递的信息。

一切都很好,但是必须为您制作的每个装饰器将其写出来,这会很烦人,而不是那么干净。取而代之的是,能够自动修改我们的装饰器而不必重新编写它们,这将是很好的……但这就是装饰器的作用!

使用以下装饰器装饰器,我们可以对装饰器进行装饰,以便可以使用带参数或不带参数的装饰器:

def doublewrap(f):    '''    a decorator decorator, allowing the decorator to be used as:    @decorator(with, arguments, and=kwargs)    or    @decorator    '''    @wraps(f)    def new_dec(*args, **kwargs):        if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): # actual decorated function return f(args[0])        else: # decorator arguments return lambda realf: f(realf, *args, **kwargs)    return new_dec

现在,我们可以使用@doublewrap装饰我们的装饰器,它们将在有或无参数的情况下工作,但有一个警告:

我在上面提到过,但是应该在这里重复一遍,此装饰器中的检查对装饰器可以接收的参数进行了假设(即,它无法接收单个可调用的参数)。由于我们现在使它适用于任何生成器,因此需要牢记或修改它,以防矛盾。

下面演示其用法:

def test_doublewrap():    from util import doublewrap    from functools import wraps    @doublewrap    def mult(f, factor=2):        '''multiply a function's return value'''        @wraps(f)        def wrap(*args, **kwargs): return factor*f(*args,**kwargs)        return wrap    # try normal    @mult    def f(x, y):        return x + y    # try args    @mult(3)    def f2(x, y):        return x*y    # try kwargs    @mult(factor=5)    def f3(x, y):        return x - y    assert f(2,3) == 10    assert f2(2,5) == 30    assert f3(8,1) == 5*7


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

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

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