Python中的装饰器函数:如何使用和实现
发布时间:2023-06-16 09:39:45
装饰器函数是一种高级概念,它可以让程序员在不改变被装饰函数源代码的情况下,通过添加一些修饰或增强功能的方式,使得被修饰的函数更加强大、灵活和易于维护。在Python中,装饰器通常用于对函数进行封装、时间统计、缓存、日志记录、输入检查、权限控制等方面。本文将介绍如何使用和实现Python中的装饰器函数。
一、如何使用装饰器函数
使用装饰器函数的方式非常简单,只需要在被装饰的函数上方添加@符号,然后接上装饰器函数名称即可。例如,下面是一个简单的装饰器函数,它能够在函数执行之前和之后打印出当前时间:
import time
def timeit(func):
def wrapper(*args, **kwargs):
print('开始时间:', time.strftime('%Y-%m-%d %H:%M:%S'))
result = func(*args, **kwargs)
print('结束时间:', time.strftime('%Y-%m-%d %H:%M:%S'))
return result
return wrapper
@timeit
def foo():
time.sleep(1)
print('执行函数foo')
foo()
上述代码中,我们定义了一个名为timeit的装饰器函数,它接收一个函数对象作为参数,然后返回一个新的函数对象wrapper,该对象能够在被装饰函数执行之前和之后打印出当前时间。通过在foo函数上方添加@timeit装饰器,我们就可以将原来的函数变成了经过增强的新函数,在执行时会自动打印出开始时间和结束时间。
二、如何实现装饰器函数
实现装饰器函数的过程其实就是定义一个函数,它接收被装饰的函数对象作为参数,然后返回一个新的函数对象,新函数对象可以在被装饰函数执行前后增加一些额外的逻辑。下面是一个常见的装饰器函数模板:
def decorator(func):
def wrapper(*args, **kwargs):
# 被装饰函数执行前的逻辑
result = func(*args, **kwargs)
# 被装饰函数执行后的逻辑
return result
return wrapper
其中,decorator函数是我们自定义的装饰器函数,它接收一个参数func,该参数是被装饰的函数对象。wrapper函数是我们新定义的函数对象,它通过调用被装饰函数,并额外添加了一些逻辑,最后返回被装饰函数的执行结果。
常用的装饰器函数有以下几种:
1. 修饰函数
def bold(func):
def wrapper(*args, **kwargs):
return "<b>" + func(*args, **kwargs) + "</b>"
return wrapper
@bold
def hello(name):
return "Hello, " + name + "!"
print(hello("world")) # 输出:"<b>Hello, world!</b>"
2. 时间统计函数
def timeit(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("函数%s的执行时间为%f秒" % (func.__name__, end-start))
return result
return wrapper
@timeit
def foo():
time.sleep(1)
foo() # 输出:函数foo的执行时间为1.002363秒
3. 日志记录函数
def logger(filename):
def decorator(func):
def wrapper(*args, **kwargs):
with open(filename, mode="a", encoding="utf-8") as f:
f.write(f"执行函数{func.__name__}的时间:{time.strftime('%Y-%m-%d %H:%M:%S')}
")
return func(*args, **kwargs)
return wrapper
return decorator
@logger("log.txt")
def foo():
time.sleep(1)
foo() # 在log.txt文件中记录函数执行的时间
4. 缓存函数
def cache(func):
cached = {}
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cached:
cached[key] = func(*args, **kwargs)
return cached[key]
return wrapper
@cache
def foo(a, b):
time.sleep(1)
return a + b
print(foo(1, 2)) # 耗时1s,输出3
print(foo(1, 2)) # 不耗时,直接输出3
5. 输入检查函数
def check_input(func):
def wrapper(*args, **kwargs):
for arg in args:
if not isinstance(arg, (int, float)):
raise TypeError("参数必须是数字类型")
return func(*args, **kwargs)
return wrapper
@check_input
def foo(a, b):
return a + b
print(foo(1, 2)) # 输出3
print(foo("1", 2)) # TypeError: 参数必须是数字类型
6. 权限控制函数
def check_permission(func):
def wrapper(*args, **kwargs):
if not user_has_permission():
raise PermissionError("无权限执行此操作")
return func(*args, **kwargs)
return wrapper
@check_permission
def foo():
return "执行foo操作"
print(foo()) # 如果没有权限,会raise PermissionError异常
以上就是使用和实现Python中装饰器函数的简单介绍,希望对读者有所帮助。
