装饰器是 Python 中的一个高级特性,它通过允许你动态地扩展或修改函数、方法或类的行为,极大地提升了代码的可重用性和模块化。理解装饰器的工作原理,能够帮助你写出更简洁、高效、可维护的代码。
1. 什么是装饰器?
在 Python 中,装饰器本质上是一个函数,它接受另一个函数作为输入,经过加工后返回一个新的函数(或修改过的函数)。装饰器通常用于扩展或修改函数的功能,而无需修改原函数的源代码。
装饰器的常见用途包括:
- 日志记录:自动记录函数调用的输入输出信息。
- 性能分析:测量函数执行时间,优化性能。
- 权限控制:限制函数的访问权限,增加安全性。
- 缓存:缓存函数结果以提高性能。
那么就需要问问各位懂行大佬!!!
哪些情况使用装饰器会比较好!!!
希望评论留言!!!
2. 装饰器的基本语法
装饰器的基本语法非常简洁,使用 @decorator_name
语法来应用装饰器。
def decorator_function(original_function):
def wrapper(*args, **kwargs):
print("函数执行前的操作")
result = original_function(*args, **kwargs)
print("函数执行后的操作")
return result
return wrapper
@decorator_function
def target_function(arg1, arg2):
print(f"原始函数执行,参数为:{arg1}, {arg2}")
在上述代码中,@decorator_function
将 target_function
作为参数传递给装饰器 decorator_function
,并将返回的 wrapper
函数替代原函数。
看过一篇文章中的等价关系:
3. 一个简单的装饰器实例
以下是一个简单的装饰器示例,在函数执行前后打印日志:
def my_decorator(func):
def wrapper():
print("在函数之前执行")
func()
print("在函数之后执行")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
输出为:
4. 带参数的装饰器
如果目标函数需要参数,你可以通过在 wrapper
函数中使用 *args
和 **kwargs
来传递这些参数:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("函数执行前")
func(*args, **kwargs)
print("函数执行后")
return wrapper
@my_decorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
输出为:
5. 带参数的装饰器工厂
装饰器本身也可以接受参数。如果你希望控制装饰器的行为,可以通过创建装饰器工厂来接受参数。例如,以下装饰器会让函数重复执行多次:
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
输出为:
6. 类装饰器:动态修改类行为
除了函数装饰器,Python 也支持类装饰器。类装饰器用于修改类的行为,它接收一个类作为参数,并返回修改后的类。类装饰器常见的应用场景包括实现单例模式、日志记录等。
6.1 函数形式的类装饰器
下面是一个类装饰器的例子,它在类方法执行前后打印日志:
def log_class(cls):
class Wrapper:
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def __getattr__(self, name):
return getattr(self.wrapped, name)
def display(self):
print(f"调用 {cls.__name__}.display() 前")
self.wrapped.display()
print(f"调用 {cls.__name__}.display() 后")
return Wrapper
@log_class
class MyClass:
def display(self):
print("这是 MyClass 的 display 方法")
obj = MyClass()
obj.display()
输出为:
6.2 类形式的类装饰器(单例模式)
类装饰器还可以用于实现单例模式,确保类的实例是唯一的:
class SingletonDecorator:
def __init__(self, cls):
self.cls = cls
self.instance = None
def __call__(self, *args, **kwargs):
if not self.instance:
self.instance = self.cls(*args, **kwargs)
return self.instance
@SingletonDecorator
class Database:
def __init__(self):
print("Database 初始化")
db1 = Database()
db2 = Database()
print(db1 is db2) # True,说明是同一个实例
输出为:
7. Python 内置装饰器
Python 提供了几个常用的内置装饰器,帮助开发者更加高效地管理类和函数。
@staticmethod
:定义静态方法,无需实例化类即可调用。@classmethod
:定义类方法,接收类本身作为第一个参数。@property
:将方法转换为属性访问。
8. 多个装饰器的堆叠
你还可以将多个装饰器堆叠在一起,它们会按照从下到上的顺序依次应用:
def decorator1(func):
def wrapper():
print("Decorator 1")
func()
return wrapper
def decorator2(func):
def wrapper():
print("Decorator 2")
func()
return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
输出为:
这里疑惑为什么 Decorator 1 后面没有 Hello! 呢???
实际输出如图片所示!!!分享
结语
装饰器是 Python 中非常强大的功能之一,它允许你在不修改原始代码的前提下,为函数或类动态添加新行为。通过理解装饰器的使用方法,你可以在工作中更加灵活地应对各种需求,从日志记录到性能优化,装饰器都是你得心应手的工具。
有什么不对的地方还请各位大哥批评指正!!!