01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
01-Python 基础语法入门:从变量到输入输出,零基础也能学会!
02-Python 流程控制终极指南:if-else 和 for-while深度解析
03-Python 列表与元组全攻略:从新手到高手的必备指南
04-Python 字典与集合:从入门到精通的全面解析
05-Python函数入门指南:从定义到应用
06-Python 函数高级特性:从默认参数到闭包的全面解析
07-Python 模块与包:从零到自定义的全面指南
08-Python异常处理:从入门到精通的实用指南
09-Python 文件操作:从零基础到日志记录实战
10-Python面向对象编程入门:从类与对象到方法与属性
11-Python类的方法与属性:从入门到进阶的全面解析
12-Python继承与多态:提升代码复用与灵活性的关键技术
13-掌握Python魔法方法:如何用__add__和__len__自定义类的行为
14-python面向对象编程总结:从基础到进阶的 OOP 核心思想与设计技巧
15-掌握 Python 高级特性:深入理解迭代器与生成器
16-用 Python 装饰器提升效率:日志与权限验证案例
嘿,朋友!你有没有遇到过这样的场景:项目上线前一天,领导突然说要给所有核心函数加个执行时间监控,或者产品经理要求某些功能只有 VIP 用户才能用。改代码?加日志?一行行手动写,太崩溃了吧!这时候,Python 的装饰器(Decorator)就像一位贴心的助手,能让你不碰原始代码,就给函数“穿上新衣”。我刚接触 Python 时,也觉得装饰器有点玄乎,但用了几次后,简直爱不释手!本文将带你从零认识装饰器,搞懂它的基本用法,再通过日志记录、权限验证这些实战案例,展示它的强大,最后还会解锁带参数的装饰器,让你的代码灵活到飞起。不管你是刚入门还是想进阶,这篇干货都能帮到你,快来一起玩转装饰器吧!
装饰器是 Python 中一种优雅的高级特性,简单来说,它就是一个“函数的包装工”,能在不改变原始函数的情况下,给它加上新功能。接下来,我们从基础概念入手,逐步拆解它的用法。
装饰器本质上是一个函数,它接收另一个函数作为参数,然后返回一个“升级版”的新函数。这个新函数通常会在原始函数执行前后,添加一些额外的操作,比如打印信息、检查条件等。它的核心优势是:代码复用和不侵入式修改。
让我们先来看一个最简单的装饰器:
def decorator(func):
def wrapper(*args, **kwargs):
print("我在函数前干点啥")
result = func(*args, **kwargs) # 调用原始函数
print("我在函数后干点啥")
return result
return wrapper
decorator
:接收目标函数 func
作为参数。wrapper
:包装原始函数,添加新功能。*args, **kwargs
:确保装饰器能适配任何参数的函数。使用装饰器非常简单,只需要在函数定义上方加上 @装饰器名
就行了:
@decorator
def say_hello():
print("Hello!")
say_hello()
输出:
我在函数前干点啥
Hello!
我在函数后干点啥
这个 @decorator
实际上等于 say_hello = decorator(say_hello)
,是不是很酷?调用 say_hello()
时,执行的其实是 wrapper
函数。
装饰器解决了什么问题?想象一下,如果你要给 10 个函数都加上日志功能,难道要在每个函数里都写一遍打印代码吗?太麻烦了!装饰器可以让你把这些“通用功能”抽出来,复用在多个函数上,既优雅又高效。
假如没有装饰器,你可能这样写:
def func1():
print("开始执行 func1")
print("func1 干了点啥")
print("func1 执行完毕")
def func2():
print("开始执行 func2")
print("func2 干了点啥")
print("func2 执行完毕")
代码重复太多!用了装饰器后:
def log(func):
def wrapper(*args, **kwargs):
print(f"开始执行 {func.__name__}")
result = func(*args, **kwargs)
print(f"{func.__name__} 执行完毕")
return result
return wrapper
@log
def func1():
print("func1 干了点啥")
@log
def func2():
print("func2 干了点啥")
func1()
func2()
输出:
开始执行 func1
func1 干了点啥
func1 执行完毕
开始执行 func2
func2 干了点啥
func2 执行完毕
这样,日志功能就被复用了,代码也更简洁!
理论讲完了,接下来看看装饰器在真实开发中的威力。我们挑两个常见场景:日志记录和权限验证。
开发中,经常需要记录函数的调用时间、参数等信息。装饰器可以帮你轻松搞定。
import time
def log_time(func):
def wrapper(*args, **kwargs):
start = time.time()
print(f"[{time.ctime()}] 调用 {func.__name__}, 参数: {args}")
result = func(*args, **kwargs)
end = time.time()
print(f"[{time.ctime()}] {func.__name__} 结束,耗时 {end - start:.2f} 秒")
return result
return wrapper
@log_time
def slow_add(a, b):
time.sleep(1) # 模拟耗时操作
return a + b
print(slow_add(3, 4))
输出:
[Tue Oct 10 10:00:00 2023] 调用 slow_add, 参数: (3, 4)
[Tue Oct 10 10:00:01 2023] slow_add 结束,耗时 1.00 秒
7
try-except
,捕获函数执行中的错误。在 Web 开发中,某些功能需要用户登录才能用。装饰器可以帮你快速实现权限检查。
def login_required(func):
def wrapper(user, *args, **kwargs):
if user.get("logged_in", False):
return func(user, *args, **kwargs)
else:
print("请先登录!")
return None
return wrapper
@login_required
def show_secret(user):
print(f"欢迎 {user['name']},这是秘密信息!")
user1 = {"name": "小明", "logged_in": True}
user2 = {"name": "小红", "logged_in": False}
show_secret(user1) # 输出: 欢迎 小明,这是秘密信息!
show_secret(user2) # 输出: 请先登录!
user
字典缺少 logged_in
键,get()
方法会返回默认值 False
,避免报错。admin_required
。普通的装饰器已经很强大了,但如果想让它更灵活怎么办?带参数的装饰器登场!
带参数的装饰器其实是一个“装饰器工厂”,它多了一层函数,用来接收参数。
def repeat(times): # 接收装饰器参数
def decorator(func): # 真正的装饰器
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3) # 装饰器带参数
def say_hi():
print("Hi!")
say_hi()
输出:
Hi!
Hi!
Hi!
repeat
:接收参数 times
,返回装饰器。decorator
:接收函数 func
。wrapper
:执行包装逻辑。假设你想根据日志级别(如 INFO、DEBUG)记录不同信息,可以用带参数的装饰器。
def log_level(level):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"[{level}] {func.__name__} 被调用")
return func(*args, **kwargs)
return wrapper
return decorator
@log_level("INFO")
def add(a, b):
return a + b
@log_level("DEBUG")
def multiply(a, b):
return a * b
add(2, 3) # 输出: [INFO] add 被调用
multiply(4, 5) # 输出: [DEBUG] multiply 被调用
可以在 wrapper
中加入 time.ctime()
,让日志更详细。
可以用字典映射不同级别到不同行为,比如 ERROR 级别时发邮件通知。
以下是根据您的要求重新撰写的“前言”和“总结”部分,以及为文章精心设计的五个吸引人心的标题。新的“前言”更加贴近真实开发场景,旨在激发读者的共鸣和兴趣;“总结”则通过分点形式提炼核心内容,帮助读者快速回顾并留下深刻印象。标题经过 SEO 优化,融入热门关键词,确保流量潜力。
装饰器是 Python 开发中的一大利器,既能提升代码复用性,又能让你的程序更优雅。从基础语法到实际应用,再到带参数的高级用法,这篇文章带你走了一遍装饰器的全流程。朋友,学会了它,你的代码就多了一份“魔法”!别犹豫,赶紧在自己的项目里试试吧,相信你会发现更多妙用。
以下是本文的核心要点总结:
@装饰器名
的语法糖实现,背后是 函数 = 装饰器(函数)
的逻辑。简单却强大!