python 装饰器

Posted 咕噜噜~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 装饰器相关的知识,希望对你有一定的参考价值。

目录

装饰器的作用

在不改变原函数(对象)本身和原函数(对象)的调用方式的情况下, 为其添加额外的功能. 再简单点说, 装饰器的作用就是为已经存在的函数或对象添加额外的功能.


装饰器的使用

被装饰函数的上方写 @decorator , 这里的符号 @ 是必须的, decorator是你定义的装饰器的名字.


装饰器(版本一)

描述: 最简单的装饰器, 原函数既没有形参也没有返回值.

def wrapper1(func):
    def inner():
        print("在原函数执行前要额外添加的功能")
        func()
        print("在原函数执行后要额外添加的功能")

    return inner

实例说明:

def wrapper1(func):     # 自定义一个装饰器wrapper1
    def inner():
        print("在原函数执行前要额外添加的功能")
        func()
        print("在原函数执行后要额外添加的功能")
        
    return inner


@wrapper1   # 使用装饰器
def func():
    print("我是原函数func")

    
func()  # 调用原函数


### 执行结果:
在原函数执行前要额外添加的功能
我是原函数func
在原函数执行后要额外添加的功能

装饰器(版本二)

描述: 原函数有返回值, 但没有任何形参.

def wrapper2(func):
    def inner():
        print("在原函数执行前要额外添加的功能")
        ret = func()    # 在这里ret接收func的返回值
        print("在原函数执行后要额外添加的功能")
        return ret      # inner函数会返回"原函数的返回值"

    return inner

实例说明:

def wrapper2(func):
    def inner():
        print("在原函数执行前要额外添加的功能")
        ret = func()    # 在这里ret接收func的返回值
        print("在原函数执行后要额外添加的功能")
        return ret      # inner函数会返回"原函数的返回值"

    return inner


@wrapper2
def func2():
    print("我是原函数func2")
    return "我是原函数func2的返回值"


ret = func2()
print(ret)


### 执行结果:
在原函数执行前要额外添加的功能
我是原函数func2
在原函数执行后要额外添加的功能
我是原函数func2的返回值

装饰器(版本三)

描述: 原函数不仅有返回值, 而且还有参数

def wrapper3(func):
    def inner(*args, **kwargs):      # inner函数接收所有参数
        print("在原函数执行前要额外添加的功能")
        ret = func(*args, **kwargs)  # func函数拿到所有参数
        print("在原函数执行后要额外添加的功能")
        return ret

    return inner

实例说明:

def wrapper3(func):
    def inner(*args, **kwargs):  # inner函数接收所有参数
        print("在原函数执行前要额外添加的功能")
        ret = func(*args, **kwargs)  # func函数拿到所有参数
        print("在原函数执行后要额外添加的功能")
        return ret

    return inner


@wrapper3
def func3(name):
    print("我是原函数<{}>".format(name))
    return "我是原函数<{}>的返回值".format(name)


ret = func3(name="function3")   # 设置函数func3的形参name="function3"
print(ret)


### 执行结果:
在原函数执行前要额外添加的功能
我是原函数<function3>
在原函数执行后要额外添加的功能
我是原函数<function3>的返回值

装饰器(进阶版)

描述: 如果我们存在这样的需求----当我们给所有需要添加额外功能的函数加上装饰器以后, 某一天, 产品经理突然告诉我们, 这些地方需要这些额外功能, 另外一些地方却又不需要这些额外功能了, 此时我们该怎么办呢? 没关系, 我们还有另外一种简单便捷的方法来解决这个问题. 即: 带参数的装饰器. 有了参数的装饰器可以让我们更加随心所欲地给函数添加或关闭额外功能.

def outer1(flag=True):      # 参数flag默认为True
    def wrapper(func):
        def inner(*args, **kwargs):
            if flag:        # 当flag为'真'时, 给原函数添加额外功能
                print("在原函数执行前要额外添加的功能")
                ret = func(*args, **kwargs)
                print("在原函数执行后要额外添加的功能")
            else:           # 当flag为'假'时, 对原函数不进行任何操作
                ret = func(*args, **kwargs)
            return ret

        return inner

    return wrapper

实例说明:

def outer2(flag=True):
    def wrapper(func):
        def before():
            print('我是函数before,我在原函数之前执行')

        def after():
            print('我是函数after,我在原函数之后执行')

        def inner(*args, **kwargs):
            if flag:
                before()
                ret = func(*args, **kwargs)
                after()
            else:
                ret = func(*args, **kwargs)
            return ret

        return inner

    return wrapper


@outer2()
def func(name):
    print("我是原函数<{}>".format(name))
    return "我是原函数<{}>的返回值".format(name)


ret = func("function1")
print(ret)


### 执行结果:
我是函数before,我在原函数之前执行
我是原函数<function1>
我是函数after,我在原函数之后执行
我是原函数<function1>的返回值

需要注意的是, 以上代码只是给装饰器加装饰器的其中一种做法, 事实上, 你是可以根据你的产品需求, 来任意改变装饰器内部的业务逻辑的.

以上是关于python 装饰器的主要内容,如果未能解决你的问题,请参考以下文章

[TimLinux] Python 装饰器

python装饰器

python装饰器关键代码

Python装饰器

python之装饰器

python 装饰器