装饰器入门
2026/7/3大约 4 分钟
1.装饰器概述
1.1 什么是装饰器
装饰器的本质是一个闭包函数,目的是在不改变原有函数的基础上,对其功能做增强。
装修队比喻
装饰器就像装修队:
- 买了一套毛坯房(原函数)
- 叫装修队过来装修(装饰器)
- 装修队在不改变房屋结构的情况下,对房屋做装饰(功能增强)
- 不能把墙砸了改成大平层(不能改变原函数功能)
1.2 装饰器的作用
一句话:在不改变原有函数的基础上,对其功能做增强。
# 原函数
def comment():
print("发表评论")
# 想要的效果:发表评论前先登录
# 登录中...
# 登录成功
# 发表评论应用场景:
- 发表评论前需要登录
- 充值前需要登录
- 删除前需要确认
- 任何需要在原函数前后增加额外功能的场景
1.3 装饰器的构成条件
| 条件 | 说明 |
|---|---|
| 有嵌套 | 外部函数嵌套内部函数 |
| 有引用 | 内部函数使用外部函数的变量 |
| 有返回 | 外部函数返回内部函数名 |
| 有额外功能 | 给需要装饰的原有函数增加额外功能 |
注意
前三个条件与闭包相同,第四个条件是装饰器特有的——必须有额外功能,否则装饰器没有意义。
2.装饰器入门
2.1 传统写法
语法格式:
装饰后的函数名 = 装饰器名(被装饰的原函数名)
装饰后的函数名()代码示例:
# 1. 定义装饰器
def login(fun_name):
def fun_inner():
print('登录中...')
fun_name() # 调用原函数
return fun_inner
# 2. 定义原函数
def comment():
print("发表评论")
# 3. 传统方式装饰
comment = login(comment) # 装饰器名(被装饰的函数名)
comment() # 调用装饰后的函数执行结果:
登录中...
发表评论2.2 传统写法图解
步骤1: comment = login(comment)
┌─────────────────────────────────┐
│ login(fn_name) │
│ fn_name = comment (原函数对象) │
│ return fun_inner (装饰后的函数)│
└─────────────────────────────────┘
comment 现在指向 fun_inner
步骤2: comment()
┌──────────────────────────────────┐
│ fun_inner() │
│ print('登录中...') ← 额外功能 │
│ fn_name() ← 调用原函数│
│ print('发表评论') ← 原函数功能 │
└──────────────────────────────────┘2.3 语法糖写法
语法格式:
@装饰器名
def 原函数名():
pass
# 直接调用原函数即可
原函数名()代码示例:
# 1. 定义装饰器
def login(fun_name):
def fun_inner():
print('登录中...')
fun_name()
return fun_inner
# 2. 语法糖方式装饰
@login
def payment():
print("充值")
# 3. 直接调用原函数
payment()执行结果:
登录中...
充值2.4 语法糖的本质
语法糖是传统写法的简化版,底层原理相同:
# 语法糖写法
@login
def payment():
print("充值")
# 等价于传统写法
def payment():
print("充值")
payment = login(payment)说明
@装饰器名 写在原函数上方,之后直接调用原函数即可,不需要手动接收装饰后的返回值。
3.装饰器的两种写法对比
3.1 传统写法 vs 语法糖
| 写法 | 语法 | 特点 |
|---|---|---|
| 传统写法 | 函数名 = 装饰器名(函数名) | 显式调用,需要手动接收返回值 |
| 语法糖 | @装饰器名 | 简洁,最常见也最常用 |
3.2 选择建议
推荐使用语法糖
语法糖是最常见也最常用的写法,实际开发中绝大多数情况下使用语法糖。
4.装饰器的实际应用
4.1 类方法中的装饰器
在之前学习类方法和静态方法时,已经接触过装饰器:
class Student:
@staticmethod
def show():
print("我是静态方法")
@classmethod
def create(cls):
print("创建学生")说明:
@staticmethod和@classmethod都是装饰器- 它们是 Python 内置的装饰器,用于修改方法的行为
- 实际开发中,更多的是使用别人写好的装饰器,而不是自己定义
4.2 装饰器的优势
- 不改变原函数:原函数的代码不需要任何修改
- 灵活增强:可以随时添加或移除装饰器
- 代码复用:同一个装饰器可以装饰多个函数
# 同一个装饰器装饰多个函数
@login
def comment():
print("发表评论")
@login
def payment():
print("充值")
@login
def delete():
print("删除")5.装饰器入门总结
5.1 装饰器的本质
- 装饰器的本质是闭包函数
- 作用:在不改变原有函数的基础上,对其功能做增强
5.2 装饰器的构成条件
| 条件 | 说明 |
|---|---|
| 有嵌套 | 外部函数嵌套内部函数 |
| 有引用 | 内部函数使用外部函数的变量 |
| 有返回 | 外部函数返回内部函数名 |
| 有额外功能 | 给原函数增加额外功能 |
5.3 两种写法
- 传统写法:
装饰后的函数名 = 装饰器名(被装饰的函数名) - 语法糖:
@装饰器名(最常用)
5.4 注意事项
常见错误
- 语法糖
@装饰器名不要加小括号,加小括号表示调用 - 装饰器必须有额外功能,否则没有意义
- 实际开发中更多是使用别人写好的装饰器,而不是自己定义
