Python装饰师
#python #advanced #pythondecorators

Python是一种解释的,面向对象的,高级编程语言。

装饰器是函数,允许用户在不更改其结构的情况下向现有对象添加新功能。

先决条件

  1. 对Python函数的基本理解。
  2. ** args和** kwargs

python函数定义为第一类对象。这意味着可以将python函数分配给变量,将它们作为参数传递给其他函数,嵌套在其他函数中,并在其他函数中返回它们为值。

对python装饰师很好地掌握了我们首先将这种功能概念作为一流的对象。

1.将功能分配给变量

在这里,我们将通过创建一个用“ Hello World”消息向用户致意的函数来演示此概念。

def greet():
    return "Hello World"
message = greet
print(message())

上述代码的输出是Hello World

2.将功能作为参数

我们将通过创建两个功能来说明。问候函数将返回字符串Hello World,呼叫函数将接受函数作为参数,然后返回参数。

def greet():
    return "Hello World"

def call_function(function):
    return function()

print(call_function(greet))

上述代码的输出是Hello World

3.嵌套功能

python还允许嵌套功能。这个概念在装饰器中至关重要。

def main():
    def greet():
        return "Hello World"
    return greet()

print(main())

输出如果上述功能为Hello World

4.在其他功能中返回功能

也可以通过另一个函数生成一个函数。

def main():
    def say_hello():
        return "Hello"
    return say_hello
main_func = main()
print(main_func())

输出为Hello

创建装饰器

通过作为头等对象的函数概念,我们现在将创建第一个装饰器。 Python装饰器与嵌套功能非常相似。为此,我们将创建两个函数,一个内部函数和一个外部函数,其中内部函数嵌套在外部函数内部。

def make_lowercase(function):
    def wrapper():
        func = function()
        return func.lower()
    return wrapper

我们可以清楚地看到,我们的装饰师将功能作为参数。我们现在将创建一个函数并将其传递给我们的装饰函数。

def say_hello():
    return "HELLO WORLD"

decorator = make_lowercase(say_hello)
print(decorator())

输出为hello world

python还提供了另一种将装饰器分配给功能的方法。我们可以使用 @符号,然后是装饰器的名称。

@make_lowercase
def say_hello():
    return "HELLO WORLD"

print(say_hello())

输出为Hello World

使用多个装饰器

我们还可以在Python功能中应用多个装饰器。例如,假设我们还希望将功能执行延迟5秒。然后,我们将定义用于延迟功能执行的装饰函数。

import time
def delay(function):
    def wrapper():
        time.sleep(5)
        return function()
    return wrapper
@delay()
@make_lowercase
def say_hello():
    return "HELLO WORLD"

print(say_hello())

输出仍然是Hello World,但是函数的执行say_hello被延迟了5秒。

用参数定义装饰函数

我们还可以定义接受参数的装饰函数。我们将通过定义包装函数中的参数来做到这一点,在该函数中,此参数将传递给在运行时装饰的功能。

def make_title(function):
    def wrapper(arg1):
        function(arg1.title())
    return wrapper

@make_title
def book(title):
    print(f"The title of the book is {title}")

book("broken glass")

上面的摘要的输出是The title of the book is Broken Glass,其中参数为python的标题格式。

装饰器功能 *args和** kwargs

我们可以定义一个接受 *args和** kwargs的装饰函数。 *args存储所有位置参数,** kwargs存储所有关键字参数。

def decorate(function):
    def wrapper(*args, **kwargs):
        print(f"The args are {args}")
        print(f"The kwargs are {kwargs}")
        function(*args, **kwargs)
    return wrapper

@decorate
def function_with_no_arguments():
    print("Has no arguments")

function_with_no_arguments()

我们定义了一个接受参数并将参数传递给装饰功能的装饰符。我们还定义了一个名为function_with_no_arguments的函数,该函数不接受参数并使用装饰函数进行装饰。该功能的输出为

The args are ()
The kwargs are {}
Has no arguments

现在让使用位置参数装饰功能。

@decorate
def function_with_arguments(arg1, arg2):
    print("This function has arguments")

function_with_arguments("Python", "Java")

function_with_arguments的输出是:

The args are ('Python', 'Java')
The kwargs are {}
This function has arguments

我们可以看到Args Python和Java被打印到控制台。

让我们看看关键字参数的函数看起来像。

@decorate
def function_with_kwargs(**kwargs):
    print("Has kwargs")

function_with_kwargs(car="Subaru", model="SUBARU CROSSTREK SUV 2021")

function_with_arguments的输出是:

The args are ()
The kwargs are {'car': 'Subaru', 'model': 'SUBARU CROSSTREK SUV 2021'}
Has kwargs

我们可以看到Args Python和Java被打印到控制台。

结论

我们已经看到了如何将函数定义为Python中的一类对象。另外,我们也看到了如何在Python中定义装饰师。 Python中的装饰器有助于观察Python中的干概念,这不是重复自己。 Python中的装饰器有各种用例:

  1. 使用内置@lru_cache
  2. 缓存
  3. 在诸如Django,Blask和Fastapi之类的框架中使用