跳到主要内容

函数高阶-装饰器

  1. 装饰器的概念

软件开发中的“开放-封闭”原则,规定已经实现的功能代码不应该被修改,但可以被扩展,即:

  • 封闭:已实现的功能代码块不应该被修改
  • 开放:对现有功能的扩展开放

装饰器的作用:在不修改原函数的前提下增加函数的功能

装饰器概念:是一个闭包,把一个函数作为参数然后返回一个替代版的函数,本质上是一个返回函数的函数

  1. 简单的装饰器

    原函数:

    def func():
    print("原功能")
    func()

    加装饰器:

    # 参数f:要给哪个函数增加功能,那么就在调用wrapper()函数时传递那个函数
    def wrapper(f):
    # inner()函数即为替代版函数,要实现原函数的功能,并增加新功能
    def inner():
    print("扩展功能") # 增加新功能
    f() # 实现原函数功能
    return inner

    def func():
    print("原功能")

    func = wrapper(func)
    func()
  1. 使用@符号装饰

    python2.4开始支持。在函数定义时加上"@装饰器名称"即可完成装饰操作。

    如上面的func = wrapper(func)等同于:在fuc()函数定义上面加@wrapper

    def wrapper(f):
    def inner():
    print("扩展功能") # 增加新功能
    f() # 实现原函数功能
    return inner
    @wrapper
    def func():
    print("原功能")
    func()
  1. 带参数的装饰器

    def wrapper(f):
    def inner(*args):
    loginname=input("请输入用户名(可跳过):")
    f(loginname) if len(loginname)>0 else f(args)
    return inner
    print("begin")
    @wrapper
    def func(user):
    print("欢迎你, %s"%user)
    func("游客","123")
  1. 多个装饰器

    装饰时:从距离近的装饰器开始装饰

    执行时:从距离远的装饰器内部函数开始执行

    import time
    def wrapper1(f):
    def inner1():
    print("enter inner1")
    time.sleep(1)
    f()
    time.sleep(1)
    print("exit inner1")
    return inner1

    def wrapper2(f):
    def inner2():
    print("enter inner2")
    time.sleep(1)
    f()
    time.sleep(1)
    print("exit inner2")
    return inner2

    def wrapper3(f):
    def inner3():
    print("enter inner3")
    time.sleep(1)
    f()
    time.sleep(1)
    print("exit inner3")
    return inner3
    print("开始装饰")
    @wrapper1
    @wrapper2
    @wrapper3
    def say():
    print("这是原函数")

    print("开始执行")
    say()

    装饰过程:

    morewrapperstep

    执行过程:

    morewrapperexecstep

    执行结果:

    morewrapperresult