一、装饰器概述
装饰器允许开发者在不修改原函数代码的情况下,给函数添加额外的功能
装饰器本质上是一个返回函数的高阶函数
在 Python 中,使用装饰器语法糖
@可以便捷应用装饰器
二、函数概念
1、函数是一等对象
- 函数可以赋值给变量
defgreet(name):returnf"Hello,{name}"my_func=greetprint(my_func("Alice"))# 输出结果 Hello, Alice- 函数可以作为参数传递
defgreet(name):print(f"Hello,{name}")defcall_twice(func,arg):greet(arg)greet(arg)call_twice(greet,"Alice")# 输出结果 Hello, Alice Hello, Alice- 可以定义在另一个函数内部
defcall_twice(arg):defgreet(name):returnf"Hello,{name}"print(greet(arg)+" "+greet(arg))call_twice("Alice")# 输出结果 Hello, Alice Hello, Alice- 函数可以作为返回值
defget_func(flag):defadd(num1,num2):returnnum1+num2defsubtract(num1,num2):returnnum1-num2ifflag=="+":returnaddelifflag=="-":returnsubtract result_func=get_func("+")result=result_func(10,20)print(result)# 输出结果 302、闭包
闭包是嵌套函数中,内部函数引用外部函数的变量,即使外部函数已经执行完毕
如下例,函数 inner_func 引用了外部函数的变量 x,即使函数 outer_func 已经执行完,函数 closure 仍能访问 x
defouter_func(x):definner_func(y):returnx+yreturninner_func closure=outer_func(10)result=closure(5)print(result)# 输出结果 15三、装饰器手动实现
- 基本实现
# 装饰器函数defmy_decorator(func):defwrapper():print("函数执行前")result=func()print("函数执行后")returnresultreturnwrapper# 原始函数defsay_hello():print("Hello")# 应用装饰器decorated_say_hello=my_decorator(say_hello)decorated_say_hello()# 输出结果 函数执行前 Hello 函数执行后- 函数带参数
# 装饰器函数defmy_decorator(func):defwrapper(**kwargs):print("函数执行前")result=func(**kwargs)print("函数执行后")returnresultreturnwrapper# 原始函数defsay_hello(name):print(f"Hello,{name}")# 应用装饰器decorated_say_hello=my_decorator(say_hello)decorated_say_hello(name="Alice")# 输出结果 函数执行前 Hello, Alice 函数执行后- 装饰器带参数
# 装饰器函数defmy_decorator(func,times):defwrapper():print("函数执行前")foriinrange(times):func()print("函数执行后")returnwrapper# 原始函数defsay_hello():print("Hello World")# 应用装饰器decorated_say_hello=my_decorator(say_hello,3)decorated_say_hello()# 输出结果 函数执行前 Hello World Hello World Hello World 函数执行后四、装饰器语法糖实现
- 基本实现
# 装饰器函数defmy_decorator(func):defwrapper():print("函数执行前")result=func()print("函数执行后")returnresultreturnwrapper# 应用装饰器@my_decoratordefsay_hello():print("Hello")say_hello()# 输出结果 函数执行前 Hello 函数执行后- 函数带参数
# 装饰器函数defmy_decorator(func):defwrapper(**kwargs):print("函数执行前")result=func(**kwargs)print("函数执行后")returnresultreturnwrapper# 应用装饰器@my_decoratordefsay_hello(name):print(f"Hello,{name}")say_hello(name="Alice")# 输出结果 函数执行前 Hello, Alice 函数执行后- 装饰器带参数
# 装饰器函数defmy_decorator(times):defdecorator(func):defwrapper():print("函数执行前")foriinrange(times):func()print("函数执行后")returnwrapperreturndecorator# 应用装饰器@my_decorator(times=3)defsay_hello():print("Hello World")say_hello()# 输出结果 函数执行前 Hello World Hello World Hello World 函数执行后