Python函数的高级特性 - 装饰器
Python中的装饰器是一种用于修改、包装或增强现有函数功能的函数。通过装饰器,可以更灵活地对现有的代码进行修改,使其具有更好的可维护性、可复用性和可扩展性。
装饰器语法
装饰器的基本语法如下:
def decorator(func):
def wrapper(*args, **kwargs):
# 在 func() 前执行的代码
result = func(*args, **kwargs)
# 在 func() 后执行的代码
return result
return wrapper
@decorator
def func():
pass
其中,decorator 函数是装饰器函数,在这里它将会被应用到 func 函数上面。在 decorator 函数内部定义了一个名为 wrapper 的新函数,这个新函数将会代替原来的 func 函数。wrapper 函数的参数与 func 函数的参数相同,然后在函数体内部执行了一些额外的代码,最后再调用原始函数 func。使用 @decorator 将函数装饰器与被装饰函数连接在一起,就完成了装饰器的应用。
装饰器的应用
装饰器的应用非常广泛,常见的用途包括:
1. 记录日志信息
可以使用装饰器来记录函数的执行过程,比如函数的调用时间、执行时间、耗时等。
import time
def log_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__}() costs {end_time - start_time:.5f}s")
return result
return wrapper
@log_time
def fib(n):
if n < 2:
return n
else:
return fib(n-1) + fib(n-2)
print(fib(30))
在这个例子中,我们使用 log_time 装饰器记录了 fib 函数的执行时间,最终打印出了耗时的结果。
2. 缓存计算结果
如果一个函数的调用结果是不变的,那么可以通过使用装饰器来将这个结果缓存起来,这样下一次调用该函数时就可以直接返回缓存的结果而不需要重新计算。
def memoize(func):
cache = dict()
def wrapper(*args):
if args in cache:
return cache[args]
result = func(*args)
cache[args] = result
return result
return wrapper
@memoize
def fib(n):
if n < 2:
return n
else:
return fib(n-1) + fib(n-2)
print(fib(100))
在这个例子中,我们使用 memoize 装饰器将 fib 函数的计算结果缓存起来,然后在下一次计算时直接返回缓存的结果,从而减少了计算量。
3. 认证和授权
可以使用装饰器来授权和限制用户的访问权限,比如可以使用装饰器来限制某些函数只能被管理员或者特定用户访问。
def login_required(func):
def wrapper(*args, **kwargs):
if current_user.is_authenticated:
return func(*args, **kwargs)
else:
raise Exception("Unauthorized access")
return wrapper
@login_required
def delete_user(user_id):
# 删除用户的具体实现
pass
在这个例子中,我们使用 login_required 装饰器限制 delete_user 函数只能被已经登录的用户访问,从而保护了用户数据的安全。
4. 处理异常
可以使用装饰器来处理函数执行过程中可能出现的异常,比如可以使用装饰器来捕获函数中的异常并返回一个默认值,或者记录异常信息并重试等。
def retry(times):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(times):
try:
result = func(*args, **kwargs)
return result
except:
pass
raise Exception(f"Function {func.__name__} failed after {times} retries")
return wrapper
return decorator
@retry(3)
def do_something():
# 实现函数的具体逻辑
pass
在这个例子中,我们使用 retry 装饰器来重试 do_something 函数的执行,最多尝试三次,如果三次以后仍然失败则抛出异常。通过装饰器的方式,我们可以使得函数的实现保持清晰简洁,而将异常处理逻辑封装在装饰器函数中。
总结
装饰器是 Python 中的一项基础技术,但在实际应用中具有广泛的应用。通过装饰器,我们可以更灵活地对现有的函数进行修改和增强,从而提高程序的可维护性、可复用性和可扩展性。熟练掌握装饰器技术,对于提高编程效率和编写高质量代码都具有重要意义。
