程序员文章、书籍推荐和程序员创业信息与资源分享平台

网站首页 > 技术文章 正文

通俗地讲解Python的装饰器

hfteth 2025-05-16 13:29:56 技术文章 11 ℃

1. 装饰器的概念类比

装饰器就像是给函数“穿上”一件额外的“衣服”。想象一下,你有一个函数,它就像一个人,能完成某些任务(比如计算两个数的和)。装饰器就是给这个人添加额外的功能,比如在计算和之前先检查输入的数字是否符合要求,或者在计算完成后记录一下计算的时间。

从另一个角度看,装饰器就像手机的保护壳。手机本身(函数)有基本的功能,如打电话、发短信。而保护壳(装饰器)可以给手机添加新的功能,比如防水、防摔,这些新功能不会改变手机本身打电话、发短信的基本功能,但可以增强手机的整体性能。

2. 简单的装饰器示例代码解释

首先,来看一个最基本的装饰器的结构:

```python
def decorator_function(func):
def wrapper():
print("在函数执行前做一些事情")
func()
print("在函数执行后做一些事情")
return wrapper
```

这里定义了一个名为`decorator_function`的函数,它接受一个函数`func`作为参数。这个`decorator_function`就是我们的装饰器。

然后在装饰器内部,定义了一个新的函数`wrapper`。这个`wrapper`函数就像是给原来的函数`func`穿上的“衣服”。

当调用`wrapper`函数时,它会先执行`print("在函数执行前做一些事情")`,这就是在函数执行前添加的额外功能。然后调用`func()`,这就是执行原来的函数。最后执行`print("在函数执行后做一些事情")`,这是在函数执行后添加的功能。

最后,装饰器返回`wrapper`函数。

假设我们有一个简单的函数:

```python
def say_hello():
print("Hello!")
```

要使用装饰器来装饰这个函数,我们可以这样做:

```python
decorated_say_hello = decorator_function(say_hello)
decorated_say_hello()
```

首先,`decorator_function(say_hello)`这一步是把`say_hello`函数传递给装饰器`decorator_function`。然后返回的`wrapper`函数被赋值给`decorated_say_hello`。最后调用`decorated_say_hello()`,就会执行`wrapper`函数,从而实现了在`say_hello`函数执行前后添加额外功能。

3. 语法糖形式的装饰器解释

在Python中,还有一种更简洁的使用装饰器的方式,叫做语法糖。上面的代码可以改写为:

```python
@decorator_function
def say_hello():
print("Hello!")
```

这种`@`符号的写法就相当于`say_hello = decorator_function(say_hello)`。它让代码看起来更简洁,也更符合Python的编程习惯。

4. 装饰器的实际用途举例

日志记录

假设你有一个函数用于处理用户的订单,你想记录每次调用这个函数的时间和参数等信息。

```python
import time
def log_decorator(func):
def wrapper(*args, kwargs):
start_time = time.time()
print(f"开始调用函数 {func.__name__},参数为{args}和{kwargs}")
result = func(*args, kwargs)
end_time = time.time()
print(f"函数 {func.__name__} 执行完成,耗时{(end_time start_time)}秒")
return result
return wrapper
@log_decorator
def process_order(order_id, product_name):
print(f"正在处理订单 {order_id},产品为{product_name}")
# 模拟订单处理时间
time.sleep(2)
return "订单处理成功"
```

在这里,`log_decorator`是一个装饰器,它可以记录`process_order`函数的调用时间、参数等信息。当调用`process_order`函数时,会自动执行装饰器中的代码,在函数执行前后添加日志记录的功能。

权限验证

如果你有一个网页应用的后端函数,用于获取用户的敏感信息,你可能需要验证用户是否有访问权限。

```python
def permission_check_decorator(func):
def wrapper(user):
if user.has_permission():
return func(user)
else:
print("用户没有权限访问此功能")
return wrapper
class User:
def __init__(self, has_permission):
self.has_permission = has_permission
@permission_check_decorator
def get_user_info(user):
print("获取用户信息")
return "用户的详细信息"
```

在这个例子中,`
permission_check_decorator`装饰器会检查用户对象`user`是否有访问权限。如果有,就执行`get_user_info`函数来获取用户信息;如果没有,就打印提示信息。这样就可以通过装饰器方便地给函数添加权限验证的功能。

Tags:

最近发表
标签列表