python-装饰器
装饰器
基本样式
def decorator(func):
def wrapper(*args, **kwargs):
print("before")
res = func(*args, **kwargs)
print("after")
return res
return wrapper
@decorator
def func():
print("hello")
func()
装饰器传参1
def decorator_factory(name):
"""装饰器工厂"""
def decorator(func):
def wrapper(*args, **kwargs):
print("before")
res = func(*args, **kwargs)
print("after")
return res
return wrapper
# 这样就可以获取到name的值
print(name)
return decorator
@decorator_factory(name="随便的参数")
def func():
print("hello")
func()
装饰器传参2
获取被装饰函数的参数
from functools import wraps
def decorator_factory(name):
"""装饰器工厂"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("before")
res = func(*args, **kwargs)
# 这样就可以获取到args的值,下面两种方式都可以获取到
print(a)
print(b)
print(args[0])
print(args[1])
print("after")
return res
return wrapper
# 这样就可以获取到name的值
print(name)
return decorator
@decorator_factory(name="随便的参数")
def func(a, b):
print("hello")
return a + b
a = 1
b = 2
func(a, b)
@wraps用法
@wraps 装饰器的主要作用是将被装饰函数的元信息复制到装饰器函数中。这些元信息包括函数的名称、文档字符串、参数列表等。通过使用 @wraps 装饰器,可以确保装饰器函数不会改变被装饰函数的这些重要信息。
具体来说,当你使用 @wraps 装饰器装饰一个装饰器函数时,它会将被装饰函数的元信息复制到装饰器函数中。这样做的好处是,当你访问装饰器函数的属性时,你会得到和原始被装饰函数相同的结果。如果不使用 @wraps 装饰器,装饰器函数的属性可能不会和被装饰函数相匹配,这会导致一些意想不到的问题。
因此,使用 @wraps 装饰器是一个很好的习惯,特别是在编写装饰器时,这可以确保装饰的透明性和一致性。
测验:
# 编写一个装饰器,在函数执行前打印当前时间。
import time
def time_decorator(func):
def wrapper(*args,**kargs):
print(f"现在的时间是:{time.ctime()}")
return func(*args,**kargs)
return wrapper
@time_decorator
def function1():
print("hello world")
function1()
# 编写一个装饰器,在函数执行后打印函数的返回值。
def after_decorator(func):
def wrapper(*args,**kargs):
res = func(*args,**kargs)
print(f"函数的返回值是:{res}")
return res
return wrapper
@after_decorator
def function2(a,b):
return a + b
function2(1,2)
# 编写一个装饰器,用于记录函数被调用的次数。
def count_decorator(func):
count = 0
def wrapper(*args,**kargs):
nonlocal count # 声明为全局变量
count += 1
print(f"函数被调用了{count}次")
return func(*args,**kargs)
return wrapper
@count_decorator
def function3():
print("hello world")
function3()
function3()
# 编写一个装饰器,用于限制函数的执行次数,达到限制次数后无法再次执行。
def warning_decorator(count):
def decorator(func):
def wrapper(*args, **kwargs):
wrapper.count += 1
if wrapper.count <= count:
return func(*args, **kwargs)
else:
print("函数执行次数已达上限")
wrapper.count = 0
return wrapper
return decorator
@warning_decorator(3) # 设置上限为3次
def function4():
print("hello world")
function4() # 第一次调用
function4() # 第二次调用
function4() # 第三次调用
function4() # 第四次调用,达到上限