装饰器

作者: _Irving | 来源:发表于2019-05-15 11:05 被阅读0次

    装饰器比较难理解,而我想的是记住其用法

    一、函数装饰器

    1、不带参数的函数装饰器,可以直接这样写:

    def dec(func):#接收函数
        def wrapper(*args,*kwargs):
            func()
       return wrapper#返回一个函数
    return dec

    @dec
    def do():
        。。

    2、带参数的函数装饰器,那么你就需要在原来的装饰器上再包一层,用于接收这些参数。这些参数(私货)传递到内层的装饰器里后,闭包就形成了。所以说当你的装饰器需要自定义参数时,一般都会形成闭包

    3、wrapt
    wrapt是一个功能非常完善的包,用于实现各种你想到或者你没想到的装饰器。使用wrapt实现的装饰器你不需要担心之前inspect中遇到的所有问题,因为它都帮你处理了,甚至inspect.getsource(func)也准确无误。

    a、没有参数的情况

    使用wrapt你只需要定义一个装饰器函数,但是函数签名是固定的,必须是(wrapped, instance, args, kwargs),注意第二个参数instance是必须的,就算你不用它。当装饰器装饰在不同位置时它将得到不同的值,比如装饰在类实例方法时你可以拿到这个类实例。根据instance的值你能够更加灵活的调整你的装饰器。另外,args和kwargs也是固定的,注意前面没有星号。在装饰器内部调用原函数时才带星号。

    b、有参数的情况在外面加一层


    二、类装饰器

    1、不带参数的类装饰器
    像__call__这样前后都带下划线的方法在Python中被称为内置方法,有时候也被称为魔法方法。重载这些魔法方法一般会改变对象的内部行为。上面这个例子就让一个类对象拥有了被调用的行为。

    回到装饰器上的概念上来,装饰器要求接受一个callable对象,并返回一个callable对象(不太严谨,详见后文)#其实解释传入的函数,返回一个函数。那么用类来实现也是也可以的。我们可以让类的构造函数__init__()接受一个函数,然后重载__call__()并返回一个函数,也可以达到装饰器函数的效果。

    2、带参数的类装饰器

    如果需要通过类形式实现带参数的装饰器,那么会比前面的例子稍微复杂一点。那么在构造函数里接受的就不是一个函数,而是传入的参数。通过类把这些参数保存起来。然后在重载__call__方法是就需要接受一个函数并返回一个函数。

    相关文章

      网友评论

          本文标题:装饰器

          本文链接:https://www.haomeiwen.com/subject/ctwuaqtx.html