你可能不知道的Python装饰器("Python装饰器:你可能忽略的高级用法揭秘")

原创
ithorizon 6个月前 (10-19) 阅读数 22 #后端开发

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代码。


本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门