Заметки о Python (18): декораторы

Python Технологии Nuggets призывают к публикации
Заметки о Python (18): декораторы

Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность.

Привет всем, яодна чаша в неделю, передняя часть, которая не хочет быть пьяной (завернутой). Если написанной статье посчастливилось получить вашу благосклонность, мне очень повезло~

декоратор

Декоратор: Буквально это устройство, которое украшает объект. Можно добавить новые функции или наложить ограничения или помочь вывести декорированный объект без изменения исходного кода.

Характеристика декоратора заключается в том, что функция выступает в качестве его параметра, а декоратор также имеет характеристику замыкания. Пример кода выглядит следующим образом:

# 定义一个装饰器
def decorate(func):
    def wrapper():
        func()
        print("已将学生加入学校学生名单")
        print("已将学生加入系学生名单")
        print("已将学生加入班级名单")

    return wrapper


@decorate
def student():
    print("我是小花")


student()
'''
---输出结果---
我是小花
已将学生加入学校学生名单
已将学生加入系学生名单
已将学生加入班级名单
'''

использовать**@**символ плюс имя функции** для украшения функции

Процесс выполнения: потому чтоstudentдекорированная функция, система будетstudentФункция передается в качестве параметраdecorateфункция (декораторdecorate),воплощать в жизньdecorateфункцию и присвоить возвращаемое значениеstudentфункция.

Предыдущий код эквивалентен следующему коду:

# 定义一个装饰器
def decorate(func):
    def wrapper():
        func()
        print("已将学生加入学校学生名单")
        print("已将学生加入系学生名单")
        print("已将学生加入班级名单")

    return wrapper


def student():
    print("我是小花")


# 将返回值传给f 并调用
f = decorate(student)  # 这里不能加(),不然就表示调用
f()
'''
---输出结果---
我是小花
已将学生加入学校学生名单
已将学生加入系学生名单
已将学生加入班级名单
'''

еслиstudentСуществуют непосредственно исполняемые операторы вне функции.studentВ случае с функцией она также будет выполнена.Пример кода выглядит следующим образом:

# 定义一个装饰器
def decorate(func):
    print("这是外部的代码")

    def wrapper():
        func()
        print("已将学生加入学校学生名单")
        print("已将学生加入系学生名单")
        print("已将学生加入班级名单")

    return wrapper


@decorate
def student():
    print("我是小花")


# student()
'''
---输出结果---
这是外部的代码
'''

Сценарии применения

Его можно использовать для веб-сайтов электронной коммерции, чтобы определить, вошел ли пользователь в систему, чтобы продолжить выполнение; добавление журналов и других сценариев, пример кода выглядит следующим образом:

# 定义一个装饰器
def decorate(func):
    def wrapper():
        func()
        print("正在检验用户是否登录")
        # if  # 判断是否登录的代码块
        #     pass
        print("用户已登录")

    return wrapper


@decorate  # 使用装饰器
def add_shopping_cart():
    print("添加成功")


@decorate  # 使用装饰器
def payment():
    print("付款成功")


add_shopping_cart()
payment()

'''
---输出结果---
添加成功
正在检验用户是否登录
用户已登录
付款成功
正在检验用户是否登录
用户已登录
'''

Универсальный декоратор

Поскольку параметры функции не могут быть фиксированными, эту функцию можно выполнить с помощью переменных параметров функции.

Пример кода выглядит следующим образом:

def decorate(func):
    def wrapper(*args, **kwargs):  # 使用可变参数来达到可以接受任何参数的效果
        print("正在检测中。。。")
        print(".............")
        print("检测完毕")
        func(*args, **kwargs)

    return wrapper


@decorate  # 使用装饰器
def f1():  # 无参数
    print("这个没有任何功能")


@decorate
def f2(name):  # 一个参数
    print("名字是:", name)


@decorate
def student(*students):  # 多个参数  # *students用于接收多个参数
    for ch in students:
        print(ch)


@decorate
def student_classroom(*students, classroom="前端班"):  # 接收可以赋值的参数
    print(f"这是{classroom}的学生")
    for ch in students:
        print(ch)


# 调用函数
f1()
'''
---输出结果---
正在检测中。。。
.............
检测完毕
这个没有任何功能
'''
f2("一碗周")
'''
---输出结果---
正在检测中。。。
.............
检测完毕
名字是: 一碗周
'''
student("张三", "李四", "王五")
'''
---输出结果---
正在检测中。。。
.............
检测完毕
张三
李四
王五
'''
student_classroom("张三", "李四", "王五", classroom="前端班")
'''
正在检测中。。。
.............
检测完毕
这是前端班的学生
张三
李四
王五
'''

Во избежание ошибок установите его как универсальный декоратор при определении декоратора

Многослойный декоратор

Последовательный порядок выполнения многоуровневого выполнения — изнутри наружу. Самый внутренний декоратор вызывается первым, а самый внешний декоратор вызывается последним. Пример кода выглядит следующим образом:

def maths(func):  # 定义第一个装饰器
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print("该学生已经学习了数学")

    return wrapper


def Chinese(func):  # 定义第而个装饰器
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print("该学生已经学习了语文")

    return wrapper


def English(func):  # 定义第三个装饰器
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        print("该学生已经学习了英语")

    return wrapper


@maths
@English
def student1(name):
    print(f"学生{name}已经完成了")


@English
@Chinese
@maths
def student2(name):
    print(f"学生{name}已经完成了")


# 调用函数
student1("小明")
'''
学生小明已经完成了
该学生已经学习了英语
该学生已经学习了数学
'''
student2("小花")
'''
学生小花已经完成了
该学生已经学习了数学
该学生已经学习了语文
该学生已经学习了英语
'''

Декоратор с параметрами

Декоратор с параметрами разделен на три слоя следующим образом:

Первый слой: отвечает за получение параметров декоратора

Уровень 2: отвечает за получение функций

Третий слой: отвечает за получение параметров функции

Пример кода выглядит следующим образом:

# 装饰器带参数
def outer(a):  # 第一层: 负责接收装饰器的参数

    def decorate(func):  # 第二层 : 负责接收函数

        def wrapper(*args, **kwargs):  # 第三层   负责接收函数的参数
            for i in range(a):
                print(i)
            func(*args, **kwargs)

        return wrapper  # 返出来的是:第三层

    return decorate  # 返出来的是:第二层


@outer(3)
def number():
    print("打印完毕")


number()
'''
0
1
2
打印完毕
'''

Самая внешняя функция отвечает за получение параметров декоратора, а содержимое внутри по-прежнему является содержимым исходного декоратора.