Python | 装饰器的应用实例
被装饰的函数有参数:
实例1:
代码分析:
def outer(fn): def inner(name): print(f"{name}是inner函数中的参数") print("haha") fn(name) return inner @outer def func(name): print("这是被装饰的函数") func("bingbing")
装饰器定义:
outer
是一个装饰器函数,它接受一个函数fn
作为参数。- 在
outer
内部,定义了一个新的函数inner
,它接受一个参数name
。 inner
函数会先打印一些信息,然后调用原始函数fn
,并将name
参数传递给它。- 最后,
outer
返回inner
函数。
装饰器应用:
@outer
语法将outer
装饰器应用到func
函数上。- 这相当于执行了
func = outer(func)
,即func
现在实际上是inner
函数。
函数调用:
- 当调用
func("bingbing")
时,实际上是调用了inner("bingbing")
。 inner
函数会先打印"bingbing是inner函数中的参数"
和"haha"
,然后调用原始的func
函数,并传递"bingbing"
作为参数。
原始函数执行:
- 原始的
func
函数被调用,打印 "这是被装饰的函数"。
输出结果:
bingbing是inner函数中的参数 haha 这是被装饰的函数
实例2:
如何使用装饰器来增强一个接受任意参数的函数。
代码分析:
# 被装饰的函数 def func(*args, **kwargs): print(args) print(kwargs) # 装饰器函数 def outer(fn): def inner(*args, **kwargs): print("login...") fn(*args, **kwargs) return inner # 手动应用装饰器 ot = outer(func) # 调用装饰后的函数 ot("susu", "haha", name='bingbing')
代码执行过程:
- 定义被装饰的函数:
func
是一个接受任意位置参数(*args)
和关键字参数(**kwargs)
的函数。它会打印接收到的位置参数和关键字参数。 - 定义装饰器函数:
outer
是一个装饰器函数,它接受一个函数fn
作为参数。在outer
内部,定义了一个嵌套函数inner
,它也接受任意位置参数(*args)
和关键字参数(**kwargs)
。inner
函数会先打印"login...
",然后调用原始函数fn
并传递参数*args
和**kwargs
。最后,outer
返回inner
函数。 - 手动应用装饰器:通过
ot = outer(func)
,将func
函数传递给outer
装饰器。此时,ot
指向的是inner
函数。 - 调用装饰后的函数:调用
ot("susu", "haha", name='bingbing')
,实际上是调用了inner("susu", "haha", name='bingbing')
。inner
函数会先打印"login..."
,然后调用原始的func
函数并传递参数"susu"、"haha"
和name='bingbing'
。 - 原始函数执行:原始的
func
函数被调用,打印接收到的位置参数和关键字参数。
代码执行结果:
login... ('susu', 'haha') {'name': 'bingbing'}
使用 @
语法简化代码:
可以使用 @
语法来简化装饰器的应用,而不需要手动调用 outer(func)
。例如:
# 装饰器函数 def outer(fn): def inner(*args, **kwargs): print("login...") fn(*args, **kwargs) return inner # 使用 @ 语法应用装饰器 @outer def func(*args, **kwargs): print(args) print(kwargs) # 调用装饰后的函数 func("susu", "haha", name='bingbing')
输出:
login... ('susu', 'haha') {'name': 'bingbing'}