全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

python 装饰器详解

发布时间:2024-01-24 21:00:47
发布人:xqq

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_
python教程

相关文章

python 装饰器详解

python 装饰器详解

2024-01-24
python 装饰器模式

python 装饰器模式

2024-01-24
python 装饰器函数

python 装饰器函数

2024-01-24
python 表达式求值

python 表达式求值

2024-01-24

最新文章

网络安全现在的就业薪资怎么样

网络安全现在的就业薪资怎么样

2023-12-25
学习网络安全编程好就业吗

学习网络安全编程好就业吗

2023-12-25
网络安全编程就业方向如何

网络安全编程就业方向如何

2023-12-25
网络安全培训就业方向有哪些

网络安全培训就业方向有哪些

2023-12-25
在线咨询 免费试学 教程领取