yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

    • python概述

    • python环境搭建

    • python基础语法

    • python关键字与标识符

    • python流程控制

    • python函数

      • 函数概述
      • 普通函函数
      • 函数特殊用法
      • 匿名函数lambda
      • 闭包
      • 装饰器
        • 简介
        • 简单的装饰器
        • 装饰的函数带有参数
        • 装饰的函数有返回值
        • 使用多个装饰器装饰同一个函数
        • 装饰器带有参数
        • 使用_call_方法定义装饰器
      • 偏函数
    • python内置函数

    • python面向对象

    • python模块与包

    • python文件IO与OS

    • python异常处理机制

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

  • django-DRF

  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • python基础
  • python函数
YiZhang-You
2023-05-10
目录
简介
简单的装饰器
装饰的函数带有参数
装饰的函数有返回值
使用多个装饰器装饰同一个函数
装饰器带有参数
使用_call_方法定义装饰器

装饰器

# 简介

装饰器【Decorator】:使其他函数在不需要做任何代码的变动下,为函数添加功能,装饰器的返回值也是一个函数。

本质:装饰器的本质就是一个闭包,其作用是将一个函数作为参数,返回另一个函数

  • 装饰器函数运行在函数定义的时候
  • 装饰器需要返回一个可执行的对象
  • 装饰器返回的可执行对象要兼容函数f的参数

装饰器条件:

  • 外部函数中定义了内部函数
  • 外部函数一定要有返回值,返回的值是:内部函数名
  • 内部函数调用外部函数传递的需要被装饰的函数
  • 函数作为外层函数参数

使用装饰器:

@装饰器名字
   def 函数名():
     pass
1
2
3

# 简单的装饰器

在闭包的前提下引用函数作为外层函数的参数

import time

# 装饰器带参数
def zhuang1(func):  # 1. 接收f1函数作为参数
    def wrapper(*args, **kwargs):  # 这里就要加*args,**kwargs 2.外部函数中定义了内部函数
        print("正在校验中.....")
        time.sleep(2)
        print("校验完毕.....")

        func(*args, **kwargs)  # 调用原函数f1	3.内部函数调用外部函数传递的需要被装饰的函数

    return wrapper  # 把装饰器在返回给f1 4.外部函数一定要有返回值,返回的值是:内部函数名

@zhuang1
def f1():
    print("我是户主one------one")

f1()

正在校验中.....
校验完毕.....
我是户主one------one
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 装饰的函数带有参数

import time

# 装饰器带参数
def zhuang1(func):  # 接收f1
    def wrapper(*args, **kwargs):  # 这里就要加*args,**kwargs
        print("正在校验中.....")
        time.sleep(2)
        print("校验完毕.....")
        # 调用原函数
        func(*args, **kwargs)

    return wrapper  # 把装饰器在返回给f1

sum = 10000

@zhuang1
def f1(sum):
    print("我是户主one------one", sum)

f1(sum)

@zhuang1
def f2(sum, name="abc"):
    print("我是户主{}-----two".format(name), sum)

f2(sum)

@zhuang1
def f2(sum, name="aaaaaa"):
    print("我是户主{}-----two".format(name), sum)

f2(sum, name="adfafasdasd")  # 覆盖了name的值

正在校验中.....
校验完毕.....
我是户主one------one 10000
正在校验中.....
校验完毕.....
我是户主abc-----two 10000
正在校验中.....
校验完毕.....
我是户主adfafasdasd-----two 10000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 装饰的函数有返回值

# 如果装饰的函数有返回值需要在装饰器的内部函数中用return返回 装饰函数的运行结果
def say(func):
    def inner():
        print("-----2-----")
        return func()	# 这里一定要返回原函数

    return inner

@say
def show():
    return "-----1-----"

print(show())

-----2-----
-----1-----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 使用多个装饰器装饰同一个函数

'''
如果装饰器是多层的,谁距离函数最近就优先使用哪个装饰器
'''

def zhuangfeng1(func):  # 定义装饰器1
    print("-----one---start")

    def warper():
        print("刷漆..")
        return func()  # 返回原函数

    print("end")
    return warper

def zhuangfeng2(func):  # 定义装饰器2
    print("-----two---start")

    def warper():
        print("打麻椒..")
        return func()  # 返回原函数

    print("end")
    return warper

# 使用装饰器
@zhuangfeng2
@zhuangfeng1
def fz1():
    return "户主一"

print(fz1())

"""
-----one---start
end
-----two---start
end
打麻椒..
刷漆..
户主一
"""
# 总结:多个装饰器作用于同一个函数的时候,从上往下依次执行,但是,原函数只被调用一次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 装饰器带有参数

需要定义三层函数

'''
    装饰器带参数
  带参数的装饰器是三层的
  	第一层: 负责接收装饰器的参数
  	第二层: 负责接收函数
  	第三层: 去接收函数里面的参数
'''
def outer(a):  # 第一层: 负责接收装饰器的参数
    def decorate(func):  # 第二层: 负责接收函数
        def wraper(*args, **kwargs):  # 第三层: 复制接收函数的参数
            func(*args, **kwargs)
            print("--->铺地砖{}块".format(a))

        return wraper

    return decorate

@outer(100)  # 装饰器带有参数
def house(time):
    print("我{}日期拿到了毛坯房".format(time))

house("2020-9-9")

我2020-9-9日期拿到了毛坯房
--->铺地砖100块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def check_workflow_owner(view_func):
    """检查是否是workflow的创建者"""

    def wrapper(request, *args, **kwargs):
        if request.request.workflow_id:  # 如果来自workflow通过验证
            return view_func(request, *args, **kwargs)

        user_id = request.request.id
        is_owner = WorkFlow.objects.filter(id=kwargs.get('workflow_id'),
                                           owner_id=user_id).exists()

        if is_owner or is_master(kwargs.get('workspace_id'), user_id):
            return view_func(request, *args, **kwargs)
        else:
            raise APIException('无法进行操作', code=stat.PermissionsError)

    return wrapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 使用__call__方法定义装饰器

class A(object):
    def __init__(self, func):
        self.func = func

    def __call__(self):
        print('this is call')
        return self.func()  # 调用f这个函数

@A  # 语法糖,相当于A(f)
def f():
    print('hhh')

f()  # 执行call方法
1
2
3
4
5
6
7
8
9
10
11
12
13
编辑 (opens new window)
上次更新: 2023/05/17, 23:08:21
闭包
偏函数

← 闭包 偏函数→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2025 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式