你可能不知道的Python装饰器("Python装饰器:你可能忽略的高级用法揭秘")
原创
一、Python装饰器简介
Python装饰器是一种特殊类型的函数,用于修改其他函数的功能。装饰器本质上是一个返回函数的函数,它接收一个函数作为参数,并返回一个新的函数。使用装饰器,可以在不修改原函数代码的情况下,增多原函数的一些额外功能。
二、基本装饰器用法
首先,我们来看一个最单纯的装饰器例子:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
输出最终:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
三、带有参数的装饰器
装饰器可以处理带有参数的函数,这需要使用*args
和**kwargs
来接收任意数量的位置参数和关键字参数。
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Something is happening before the function is called.")
result = func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
@my_decorator
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("Alice")
greet("Bob", greeting="Hi")
输出最终:
Something is happening before the function is called.
Hello, Alice!
Something is happening after the function is called.
Something is happening before the function is called.
Hi, Bob!
Something is happening after the function is called.
四、带有参数的装饰器
装饰器本身也可以有自己的参数。为了实现这一点,我们需要再包装一层函数。
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
print("Something is happening before the function is called.")
func(*args, **kwargs)
print("Something is happening after the function is called.")
return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
输出最终:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
五、装饰器中的functools.wraps
使用functools.wraps
可以保留原函数的元信息,如文档字符串、名字、参数列表等。
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""Wrapper function."""
print("Something is happening before the function is called.")
result = func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
return wrapper
@my_decorator
def say_hello():
"""Prints 'Hello'."""
print("Hello!")
print(say_hello.__name__)
print(say_hello.__doc__)
输出最终:
say_hello
Prints 'Hello'.
六、类装饰器
除了使用函数作为装饰器,我们也可以使用类。类装饰器需要实现__call__
方法。
class MyDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Something is happening before the function is called.")
result = self.func(*args, **kwargs)
print("Something is happening after the function is called.")
return result
@MyDecorator
def say_hello():
print("Hello!")
say_hello()
输出最终:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
七、装饰器应用实例:缓存
装饰器常用于实现缓存功能,以下是一个单纯的缓存装饰器例子。
def memoize(func):
cache = {}
def memoized_func(*args):
if args in cache:
return cache[args]
result = func(*args)
cache[args] = result
return result
return memoized_func
@memoize
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
输出最终:
55
八、总结
Python装饰器是一个非常强盛且灵活的功能,它允许我们以模块化和可重用的做法扩展函数的行为。通过本文的介绍,我们了解了装饰器的基本用法以及一些高级用法,包括处理带参数的函数、带参数的装饰器、使用functools.wraps
、类装饰器以及装饰器的实际应用。掌握这些高级用法,可以帮助我们编写更加高效和可维护的Python代码。