python 装饰器重要在哪

1. 什么是装饰器

在Python中,装饰器是一种很有用的语法机制,它允许对函数、类或语句进行修饰,以增加或修改它们的功能。其本质上是一个函数,其输入和输出都是函数,用于提供一种在不改变原有函数定义的情况下增强函数能力的方法。

简单来说,装饰器是用于修饰一些已有的函数或方法的语法结构。

def my_decorator(func):

def wrapper():

print("Before function is called.")

func()

print("After function is called.")

return wrapper

@my_decorator

def say_hello():

print("Hello!")

say_hello()

在上面的例子中,@my_decorator的作用相当于为say_hello()函数添加了my_decorator()函数作为修饰器。 运行这个修饰后的函数,会输出如下结果:

Before function is called.

Hello!

After function is called.

2. 装饰器的优点

使用装饰器的主要优点是能够更好地组织代码,并提高代码的可读性和重用性。下面是几个具体的例子:

2.1 函数计时器

装饰器可以使得函数计时更加方便,不用在代码中加入额外的计时代码。

import time

def timing_function(some_function):

def wrapper():

t1 = time.time()

some_function()

t2 = time.time()

print("Time it took to run the function:", t2 - t1, "seconds")

return wrapper

@timing_function

def my_function():

num_list = []

for num in range(0, 10000):

num_list.append(num)

print("Sum of all the numbers:", sum(num_list))

my_function()

在该例子中,@timing_function函数为my_function函数添加了一个计时器,以便测量函数运行所需的时间。

2.2 日志记录器

另一个常见的例子是使用装饰器来记录函数的日志。 使用装饰器的好处是,您可以将所有的日志代码放在一个单独的位置,并使用不同的修饰器轻松地为多个函数添加日志记录。

def log_decorator(func):

def wrapper(*args, **kwargs):

print("Function '{}' called.".format(func.__name__))

result = func(*args, **kwargs)

print("Function '{}' finished.".format(func.__name__))

return result

return wrapper

@log_decorator

def add(x, y):

return x + y

@log_decorator

def subtract(x, y):

return x - y

print(add(3,4))

print(subtract(4,1))

在这个例子中,我们使用@log_decorator函数来为addsubtract函数添加日志记录器。log_decorator函数为这些函数提供了一个统一的方式来记录它们的运行情况,从而可以更轻松地维护和调试代码。

3. 如何编写装饰器

编写装饰器的常见步骤如下:

编写装饰器函数,该函数应在其内部定义一个封装函数并返回该函数。

封装函数应包括原始函数的所有参数,并在其内部调用原始函数。

在封装函数中添加修饰器代码。

返回封装函数。

在需要修饰的函数添加修饰器。

3.1 带参数的装饰器

装饰器还可以带参数,这样就可以按需自定义函数行为。

def custom_decorator(param):

def inner_decorator(function):

def wrapper():

print("Decorated with:", param)

function()

return wrapper

return inner_decorator

@custom_decorator("abc")

def say_hello():

print("Hello world")

say_hello()

使用装饰器语法将函数包装在装饰器内并提供参数来对其进行自定义。

3.2 支持任意数量参数和关键字参数的装饰器

如果要支持任意数量参数和关键字参数,则需要使用*args**kwargs来接收和传递这些参数。

def my_decorator(some_function):

def wrapper(*args, **kwargs):

print("Something is happening before the function is called.")

result = some_function(*args, **kwargs)

print("Something is happening after the function is called.")

return result

return wrapper

@my_decorator

def my_function(a, b):

return a + b

print(my_function(2, 3))

在以上代码中,修饰器可以处理任何数量和类型的参数,因为其使用*args**kwargs来传递参数。

4. 装饰器的应用场景

装饰器的使用场景非常广泛。在这里列举了几个经典的例子:

4.1 权限控制

权限控制是一种非常常见的需求,装饰器可以非常方便地管理它。当使用@login_required时,只允许已登录的用户访问特定的页面或执行操作。

from functools import wraps

from flask import abort

from flask_login import current_user

def admin_required(func):

@wraps(func)

def decorated_view(*args, **kwargs):

if not current_user.is_admin:

abort(403)

return func(*args, **kwargs)

return decorated_view

@app.route('/admin/dashboard')

@admin_required

def admin_dashboard():

return "Admin dashboard"

上面的代码使用@admin_required装饰器来只允许管理员访问后台仪表板。

4.2 缓存函数

在一些请求量较大的网站上,为了避免频繁查询数据库,可以使用缓存装饰器来缓存函数调用结果,减少访问数据库的次数。另外,这样子的话还可以提高访问速度。

import time

def cached(timeout=10):

def decorator(func):

def wrapper(*args, **kwargs):

key = str(args) + str(kwargs)

if key in wrapper.cache and time.time() - wrapper.cache[key]["time"] < timeout:

return wrapper.cache[key]["value"]

else:

value = func(*args, **kwargs)

wrapper.cache[key] = {"value": value, "time": time.time()}

return value

wrapper.cache = {}

return wrapper

return decorator

@cached()

def slow_function():

time.sleep(5)

return 42

print("Running the function the first time...")

print(slow_function())

print("Running the function the second time...")

print(slow_function())

在以上代码中,我们提供了一个缓存装饰器来缓存大量计算时间长的函数结果,以减小服务器压力。

5. 总结

装饰器是Python语言中的一个重要特性,它能够极大地拓展Python的语言功能。 通过使用装饰器,我们可以在不改变函数的原貌情况下增加或修改函数功能,从而提高代码可读性、可重用性、可维护性。

有了装饰器语法,我们可以轻松支持带参数和任意数量参数和关键字参数的函数。 装饰器还有许多应用,例如缓存函数、权限控制等。 因此,了解装饰器是Python开发人员的重要一步。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签