理解Python装饰器看这一篇就够了("Python装饰器详解:一文彻底掌握核心原理与用法")

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

Python装饰器详解:一文彻底掌握核心原理与用法

一、装饰器简介

在Python中,装饰器是一种非常有用的功能,它允许我们以不修改原有函数定义的方案,扩展或愈发函数的行为。装饰器在很多高级Python框架和库中都有广泛的应用,例如Flask、Django等。

二、装饰器的核心原理

装饰器本质上是一个返回函数的函数。它接收一个函数作为参数,然后返回一个新的函数,这个新的函数会在执行原函数之前或之后,增多一些额外的功能。

三、装饰器的使用方法

下面我们来通过一个简洁的例子来了解装饰器的使用方法。

3.1 无参数装饰器

首先,我们定义一个无参数的装饰器。

def my_decorator(func):

def wrapper():

print("Before the function is called.")

func()

print("After the function is called.")

return wrapper

@my_decorator

def say_hello():

print("Hello, world!")

say_hello()

执行上述代码,输出最终如下:

Before the function is called.

Hello, world!

After the function is called.

3.2 带参数的装饰器

接下来,我们来看一个带参数的装饰器。

def repeat(num):

def decorator(func):

def wrapper():

for _ in range(num):

func()

return wrapper

return decorator

@repeat(3)

def say_hello():

print("Hello, world!")

say_hello()

执行上述代码,输出最终如下:

Hello, world!

Hello, world!

Hello, world!

四、装饰器的进阶用法

装饰器除了可以用来扩展函数的功能,还可以用来实现一些高级功能,如缓存、日志记录等。

4.1 缓存装饰器

下面我们来实现一个简洁的缓存装饰器,它会将函数的返回值缓存起来,如果再次调用相同的参数,则直接返回缓存的最终,而不是重新计算。

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

4.2 日志装饰器

下面我们来实现一个简洁的日志装饰器,它会记录函数的调用和返回值。

import logging

def log(func):

def wrapper(*args, **kwargs):

logging.info(f"Calling function {func.__name__} with args {args} and kwargs {kwargs}")

result = func(*args, **kwargs)

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

return result

return wrapper

@log

def add(a, b):

return a + b

add(3, 4)

执行上述代码,输出最终如下(假设logging配置正确):

INFO:root:Calling function add with args (3, 4) and kwargs {}

INFO:root:Function add returned 7

五、装饰器的高级用法

除了基本的装饰器用法,Python还赞成一些高级的装饰器特性,如装饰器类、装饰器参数等。

5.1 装饰器类

装饰器类允许我们使用面向对象的方案来定义装饰器。下面是一个装饰器类的例子:

class MyDecorator:

def __init__(self, func):

self.func = func

def __call__(self, *args, **kwargs):

print("Before the function is called.")

result = self.func(*args, **kwargs)

print("After the function is called.")

return result

@MyDecorator

def say_hello():

print("Hello, world!")

say_hello()

执行上述代码,输出最终如下:

Before the function is called.

Hello, world!

After the function is called.

5.2 装饰器参数

装饰器本身也可以接受参数,这需要我们在装饰器内部再定义一个函数来接收这些参数。下面是一个装饰器参数的例子:

def count_calls(func):

def wrapper(*args, **kwargs):

wrapper.calls += 1

return func(*args, **kwargs)

wrapper.calls = 0

return wrapper

@count_calls

def say_hello():

print("Hello, world!")

say_hello()

say_hello()

print(f"say_hello has been called {say_hello.calls} times.")

@count_calls

def add(a, b):

return a + b

add(3, 4)

add(5, 6)

print(f"add has been called {add.calls} times.")

执行上述代码,输出最终如下:

Hello, world!

Hello, world!

say_hello has been called 2 times.

7

11

add has been called 2 times.

六、总结

装饰器是Python中一种非常强盛的功能,它允许我们以模块化和可重用的方案扩展或愈发函数的行为。通过本文的介绍,我们了解了装饰器的基本原理、使用方法、进阶用法和高级用法。愿望这篇文章能够帮助你彻底掌握Python装饰器的核心原理与用法。


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

文章标签: 后端开发


热门