Python装饰器入门教程-作者:思弈云

📅 2026/7/22 2:17:45
Python装饰器入门教程-作者:思弈云
1. 引言Python 装饰器Decorator是 Python 语言中一个非常强大且优雅的特性。它允许我们在不修改原有函数代码的情况下动态地给函数添加新的功能。理解并掌握装饰器是进阶 Python 开发者的必经之路。本文将带你从零开始逐步深入理解 Python 装饰器的原理、用法和高级技巧。2. 什么是装饰器简单来说装饰器就是一个接受函数作为参数并返回一个新函数的可调用对象通常是一个函数或一个类。它的核心思想是“开闭原则”对扩展开放对修改关闭。在 Python 中使用语法糖来应用装饰器这使得代码更加简洁和易读。# 一个最简单的装饰器示例defmy_decorator(func):defwrapper():print(在函数调用前执行一些操作)func()print(在函数调用后执行一些操作)returnwrappermy_decoratordefsay_hello():print(Hello!)# 调用被装饰后的函数say_hello()运行上述代码输出结果为在函数调用前执行一些操作 Hello! 在函数调用后执行一些操作可以看到say_hello函数本身只打印了 “Hello!”但通过my_decorator装饰后它自动获得了在调用前后打印日志的能力。3. 装饰器的核心原理my_decorator语法糖的本质其实就是一次函数调用和赋值。以下两段代码是完全等价的# 使用 语法糖my_decoratordefsay_hello():print(Hello!)# 等价于defsay_hello():print(Hello!)say_hellomy_decorator(say_hello)理解这一点至关重要。装饰器my_decorator接收了原始函数say_hello作为参数然后返回了一个新的函数wrapper。之后变量名say_hello就不再指向原始函数而是指向了这个新的wrapper函数。因此当我们调用say_hello()时实际上是在执行wrapper()函数。4. 装饰器进阶用法4.1 装饰带参数的函数如果被装饰的函数需要接收参数那么wrapper函数也需要能够接收这些参数并将它们传递给原始函数。这通常通过*args和**kwargs来实现。deflog_decorator(func):defwrapper(*args,**kwargs):print(f调用函数:{func.__name__}, 参数:{args},{kwargs})resultfunc(*args,**kwargs)print(f函数{func.__name__}返回:{result})returnresultreturnwrapperlog_decoratordefadd(a,b):returnab add(3,5)# 输出:# 调用函数: add, 参数: (3, 5), {}# 函数 add 返回: 84.2 带参数的装饰器有时候我们希望装饰器本身也能接收一些参数以控制其行为。这需要再嵌套一层函数。defrepeat(num_times):defdecorator(func):defwrapper(*args,**kwargs):for_inrange(num_times):resultfunc(*args,**kwargs)returnresultreturnwrapperreturndecoratorrepeat(num_times3)defgreet(name):print(fHello,{name}!)greet(Alice)# 输出:# Hello, Alice!# Hello, Alice!# Hello, Alice!这里repeat(3)首先被调用返回了真正的装饰器decorator。然后decorator再对greet函数进行装饰。4.3 保留原函数的元信息使用装饰器后被装饰函数的元信息如__name__,__doc__等会被wrapper函数覆盖。为了解决这个问题Python 提供了functools.wraps装饰器。importfunctoolsdefmy_decorator(func):functools.wraps(func)# 保留 func 的元信息defwrapper(*args,**kwargs):print(调用前)returnfunc(*args,**kwargs)returnwrappermy_decoratordefsay_hello():一个简单的问候函数print(Hello!)print(say_hello.__name__)# 输出: say_hello而不是 wrapperprint(say_hello.__doc__)# 输出: 一个简单的问候函数最佳实践在编写装饰器时始终使用functools.wraps来保留被装饰函数的元信息。5. 实战案例性能计时器让我们来编写一个实用的装饰器用于测量函数的执行时间。importtimeimportfunctoolsdeftimer(func):functools.wraps(func)defwrapper(*args,**kwargs):start_timetime.perf_counter()resultfunc(*args,**kwargs)end_timetime.perf_counter()run_timeend_time-start_timeprint(f函数{func.__name__!r}执行耗时:{run_time:.4f}秒)returnresultreturnwrappertimerdefslow_function():time.sleep(2)return完成slow_function()# 输出: 函数 slow_function 执行耗时: 2.0001 秒6. 总结Python 装饰器是一种强大的元编程工具它通过简洁的语法实现了代码的复用和解耦。本文从基础概念出发逐步深入到带参数装饰器、保留元信息等进阶用法并通过实战案例展示了其应用场景。掌握装饰器将让你的 Python 代码更加优雅、高效和 Pythonic。