一、装饰器的基本概念和使用
- 定义装饰器
- 无参装饰器
- 有参装饰器
- 装饰器嵌套使用
二、装饰器的高级应用
- 带参数的装饰器
- 多层装饰器
- 偏函数作为装饰器
- 类装饰器与装饰器类
- 动态装饰器
三、总结与展望
- 总结
- 展望
正文:
一、装饰器的基本概念和使用
- 定义装饰器
装饰器本质上是一个接受函数作为参数的高阶函数。它可以对传入的函数进行包装,并返回一个新的函数。这个新函数通常会包含原函数的调用,并在其基础上添加一些额外的功能。 - 无参装饰器
最简单的装饰器形式是无参装饰器。这种装饰器不需要额外的参数,只需定义一个外部函数,该函数接受一个函数作为参数并返回一个新函数。例如:
```python
def my_decorator(func):
def wrapper():
return wrapperprint("Something is happening before the function is called.") func() print("Something is happening after the function is called.")
@my_decorator
def say_hello():
print("Hello!")
say_hello()
3. **有参装饰器**
有参装饰器是指装饰器本身也接受参数。要实现这样的装饰器,可以使用嵌套函数的方式。例如:
```python
def repeat(num):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
- 装饰器嵌套使用
在一个函数上可以应用多个装饰器,这被称为装饰器的嵌套使用。当有多个装饰器作用于同一个函数时,它们的执行顺序是从内到外依次执行的。例如:
```python
def bold(func):
def wrapper(args, *kwargs):
return wrapperreturn f"<b>{func(*args, **kwargs)}</b>"
def italic(func):
def wrapper(args, **kwargs):
return f"{func(args, **kwargs)}"
return wrapper
@bold
@italic
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))
二、装饰器的高级应用
1. **带参数的装饰器**
在某些情况下,我们希望为装饰器本身提供参数。要实现这一目标,可以先定义一个返回装饰器的函数。例如:
```python
def valid_age(age):
def decorator(func):
def wrapper(person):
if person['age'] >= age:
return func(person)
else:
return f"Sorry, you must be at least {age} years old."
return wrapper
return decorator
@valid_age(18)
def enter_movie(person):
return f"Welcome to the movie, {person['name']}!"
print(enter_movie({"name": "Alice", "age": 20}))
print(enter_movie({"name": "Bob", "age": 17}))
- 多层装饰器
多层装饰器指的是在一个函数上应用多个装饰器,这些装饰器之间可能存在嵌套关系。通过合理使用多层装饰器,可以实现更复杂的功能组合。例如:
```python
def make_bold(fn):
def wrapped():
return wrappedreturn f"<b>{fn()}</b>"
def make_italic(fn):
def wrapped():
return f"{fn()}"
return wrapped
@make_bold
@make_italic
def say_hello():
return "Hello, World!"
print(say_hello())
3. **偏函数作为装饰器**
偏函数是一种简化函数调用的方式。通过使用偏函数作为装饰器,可以避免重复编写相似的代码。例如:
```python
from functools import partial
from time import perf_counter as pc
def timing(f):
def inner(*args, **kwargs):
start = pc()
result = f(*args, **kwargs)
end = pc()
print(f"Function {f.__name__} took {end - start:.6f} secs")
return result
return inner
@timing
def sum_list(lst):
return sum(lst)
lst = [i for i in range(1, 1000000)]
sum_list(lst)
类装饰器与装饰器类
除了函数式装饰器外,还可以使用类来实现装饰器功能。类装饰器具有更好的可扩展性和可维护性。例如:
```python
class Timing:
def init(self, func):self.func = func
def call(self, args, *kwargs):
start = pc() result = self.func(*args, **kwargs) end = pc() print(f"Function {self.func.__name__} took {end - start:.6f} secs") return result
@Timing
def sum_list(lst):
return sum(lst)
lst = [i for i in range(1, 1000000)]
sum_list(lst)
5. **动态装饰器**
动态装饰器是指在运行时根据条件选择性地应用装饰器。这可以通过定义一个返回装饰器的函数来实现。例如:
```python
def maybe_decorator(condition):
def decorator(func):
def wrapper(*args, **kwargs):
if condition:
print("Decorator applied.")
return func(*args, **kwargs)
return wrapper
return decorator
@maybe_decorator(True)
def greet(name):
return f"Hello, {name}!"
print(greet("Alice"))