千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > python 装饰器详解

python 装饰器详解

来源:千锋教育
发布人:xqq
时间: 2024-01-24 21:00:47 1706101247

Python装饰器详解

_x000D_

Python装饰器是一种强大的语法特性,它可以在不修改原函数代码的情况下,为函数添加额外的功能。装饰器可以理解为一个闭包,它将一个函数作为输入,并返回一个新的函数作为输出。这个新函数包装了原函数,可以在调用原函数之前或之后执行一些额外的逻辑。

_x000D_

装饰器的语法比较简洁,使用@符号将装饰器函数放在被装饰函数的定义之前。下面是一个简单的装饰器示例:

_x000D_

`python

_x000D_

def decorator(func):

_x000D_

def wrapper(*args, **kwargs):

_x000D_

# 在调用原函数之前执行的逻辑

_x000D_

print("Before calling the function")

_x000D_

result = func(*args, **kwargs)

_x000D_

# 在调用原函数之后执行的逻辑

_x000D_

print("After calling the function")

_x000D_

return result

_x000D_

return wrapper

_x000D_

@decorator

_x000D_

def my_function():

_x000D_

print("Inside the function")

_x000D_

my_function()

_x000D_ _x000D_

上述代码中,decorator是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数在调用原函数之前输出"Before calling the function",在调用原函数之后输出"After calling the function"。使用@decoratormy_function函数应用了装饰器。

_x000D_

通过装饰器,我们可以实现很多有用的功能,比如日志记录、性能分析、输入验证等。下面是一些常见的装饰器应用场景:

_x000D_

**1. 日志记录**

_x000D_

`python

_x000D_

import logging

_x000D_

def log_decorator(func):

_x000D_

def wrapper(*args, **kwargs):

_x000D_

logging.info(f"Calling function {func.__name__}")

_x000D_

result = func(*args, **kwargs)

_x000D_

logging.info(f"Function {func.__name__} finished")

_x000D_

return result

_x000D_

return wrapper

_x000D_

@log_decorator

_x000D_

def my_function():

_x000D_

print("Inside the function")

_x000D_

my_function()

_x000D_ _x000D_

上述代码中,log_decorator装饰器使用了Python内置的logging模块,在调用原函数之前和之后分别记录了日志信息。

_x000D_

**2. 缓存结果**

_x000D_

`python

_x000D_

def cache_decorator(func):

_x000D_

cache = {}

_x000D_

def wrapper(*args, **kwargs):

_x000D_

key = str(args) + str(kwargs)

_x000D_

if key in cache:

_x000D_

return cache[key]

_x000D_

else:

_x000D_

result = func(*args, **kwargs)

_x000D_

cache[key] = result

_x000D_

return result

_x000D_

return wrapper

_x000D_

@cache_decorator

_x000D_

def fibonacci(n):

_x000D_

if n <= 1:

_x000D_

return n

_x000D_

else:

_x000D_

return fibonacci(n-1) + fibonacci(n-2)

_x000D_

print(fibonacci(10))

_x000D_ _x000D_

上述代码中,cache_decorator装饰器通过一个字典实现了结果的缓存,避免了重复计算。

_x000D_

**3. 计时器**

_x000D_

`python

_x000D_

import time

_x000D_

def timer_decorator(func):

_x000D_

def wrapper(*args, **kwargs):

_x000D_

start_time = time.time()

_x000D_

result = func(*args, **kwargs)

_x000D_

end_time = time.time()

_x000D_

print(f"Function {func.__name__} took {end_time - start_time} seconds")

_x000D_

return result

_x000D_

return wrapper

_x000D_

@timer_decorator

_x000D_

def my_function():

_x000D_

time.sleep(1)

_x000D_

print("Inside the function")

_x000D_

my_function()

_x000D_ _x000D_

上述代码中,timer_decorator装饰器使用了time模块,计算了函数的执行时间。

_x000D_

**问答扩展**

_x000D_

**Q1: 装饰器可以传递参数吗?**

_x000D_

A1: 是的,装饰器可以接受参数。可以定义一个装饰器工厂函数,它接受参数并返回一个装饰器函数。下面是一个接受参数的装饰器示例:

_x000D_

`python

_x000D_

def repeat(n):

_x000D_

def decorator(func):

_x000D_

def wrapper(*args, **kwargs):

_x000D_

for _ in range(n):

_x000D_

result = func(*args, **kwargs)

_x000D_

return result

_x000D_

return wrapper

_x000D_

return decorator

_x000D_

@repeat(3)

_x000D_

def say_hello():

_x000D_

print("Hello")

_x000D_

say_hello()

_x000D_ _x000D_

上述代码中,repeat是一个装饰器工厂函数,它接受一个参数n,返回一个装饰器函数decoratordecorator函数接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数会重复调用原函数n次。

_x000D_

**Q2: 能否同时应用多个装饰器?**

_x000D_

A2: 是的,可以同时应用多个装饰器。多个装饰器会按照从上到下的顺序依次应用。例如:

_x000D_

`python

_x000D_

@decorator1

_x000D_

@decorator2

_x000D_

@decorator3

_x000D_

def my_function():

_x000D_

print("Inside the function")

_x000D_ _x000D_

上述代码中,my_function函数会先应用decorator3装饰器,然后应用decorator2装饰器,最后应用decorator1装饰器。

_x000D_

**Q3: 装饰器是否会改变原函数的元数据?**

_x000D_

A3: 装饰器会改变原函数的元数据。在装饰器中,通常会使用functools.wraps装饰器来将原函数的元数据复制到新函数上。这样做可以保留原函数的名称、文档字符串、参数签名等信息。例如:

_x000D_

`python

_x000D_

import functools

_x000D_

def decorator(func):

_x000D_

@functools.wraps(func)

_x000D_

def wrapper(*args, **kwargs):

_x000D_

# ...

_x000D_

return result

_x000D_

return wrapper

_x000D_ _x000D_

上述代码中,functools.wraps装饰器将wrapper函数的元数据设置为与原函数func相同。

_x000D_

通过灵活运用装饰器,我们可以提高代码的可重用性和可维护性。装饰器为我们提供了一种简洁而强大的方式来修改函数行为,使得我们能够专注于业务逻辑的实现。无论是日志记录、性能分析还是输入验证,装饰器都能帮助我们实现这些功能,使得代码更加优雅和高效。

_x000D_
tags: python教程
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT