什么是装饰器?
装饰器是Python中一种用于包装函数或类的方法,它允许你在不改变现有代码的情况下,添加额外的功能。装饰器本质上是一个接受函数作为参数并返回一个新函数的高阶函数。
基本语法
装饰器的基本语法使用 @
符号,放在被装饰的函数或类之前。例如:
@decorator_function
def some_function():
pass
这相当于:
def some_function():
pass
some_function = decorator_function(some_function)
简单示例
让我们从一个简单的示例开始。假设我们有一个函数 say_hello
,我们希望在这个函数执行前后打印一些日志信息。可以使用装饰器来实现这个需求:
def log_decorator(func):
def wrapper(*args, **kwargs):
print("Log: Before calling function")
result = func(*args, **kwargs)
print("Log: After calling function")
return result
return wrapper
@log_decorator
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
输出将是:
Log: Before calling function
Hello, Alice!
Log: After calling function
带参数的装饰器
有时,你可能需要给装饰器传递参数。可以通过在装饰器函数外再加一层函数来实现:
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
输出:
Hello, Alice!
Hello, Alice!
Hello, Alice!
类装饰器
除了函数,装饰器也可以用来装饰类。例如,我们可以创建一个装饰器来自动为类的每个方法添加日志记录功能:
def log_methods_decorator(cls):
class Wrapper:
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattribute__(self, name):
attr = object.__getattribute__(self, name)
if callable(attr):
def wrapped(*args, **kwargs):
print(f"Calling {name}")
result = attr(*args, **kwargs)
print(f"{name} finished")
return result
return wrapped
else:
return attr
return Wrapper(cls)
@log_methods_decorator
class MyClass:
def greet(self, name):
print(f"greet {name}")
def farewell(self, name):
print(f"farewell {name}")
obj = MyClass()
obj.greet("Alice")
obj.farewell("Alice")
输出:
Calling greet
greet Alice
greet finished
Calling farewell
farewell Alice
farewell finished
高级应用:单例模式装饰器
单例模式是一种确保一个类只有一个实例的设计模式。我们可以使用装饰器来实现单例模式:
def singleton(cls):
instances = {
}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class SingletonClass:
pass
obj1 = SingletonClass()
obj2 = SingletonClass()
assert obj1 is obj2 # True, only one instance created
结论
装饰器是Python中一种非常强大的工具,可以简化代码、增强可读性并避免重复。无论是简单的日志记录还是复杂的设计模式实现,装饰器都能提供优雅的解决方案。希望本文能帮助你更好地理解和应用装饰器,在日常编程中发挥更大的作用。