前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python装饰器, 就这?

Python装饰器, 就这?

作者头像
我是胖虎啊
发布2022-06-27 18:06:21
1880
发布2022-06-27 18:06:21
举报
文章被收录于专栏:测试开发卷货

前言

本篇采用简单的例子来讲下「python的装饰器」.

「目标」是: 大家看完以后, 可以达到自己「手写一个简单装饰器」的效果!

闭包

定义: 函数的形式是函数嵌套函数的形式,其中内部函数调用外部函数传入的变量值,并且外部函数最终返回内部函数的引用, 那么内部函数称为「闭包」

举个例子来解释一下

代码语言:javascript
复制
def outer(a):
    b = 10
    def inner():
        print(a + b)

    # 外函数返回内函数的引用
    return inner

if __name__ == '__main__':
    demo = outer(5)
    print(demo)  # <function outer.<locals>.inner at 0x000001EDAD6D88B8>
    demo()  # 15
  1. 首先「函数引用」可以简单理解为函数地址(类似go中的指针)。在python中可以简单理解为, 使用 「函数引用()」 即可运行该函数地址所对应的函数
  2. 使用 demo = outer(5)后, demo即为inner函数的引用.然后使用demo(),相当于使用inner().
  3. inner函数接收了外部传入的 a=5, 以及内部定义的局部变量 b=10, 最后输出15

装饰器

上面介绍了闭包, 外部函数接收到的是一个变量, 如果把接收这个变量->接收函数的引用, 那么就可以理解为是个装饰器了

装饰器的主要作用: 在不改变原来函数的基础上, 为函数增添一些额外功能

装饰器的常见应用: 「统计函数运行时间」, 「进行登录鉴权」等.下面通过2个示例简单介绍下

「统计函数运行时间的装饰器」

代码语言:javascript
复制
import time


def collect_time(func):
    def test():
        t1 = time.time()
        func()
        t2 = time.time()
        print("运行时间为: ", t2 - t1)
    return test


# 常见写法
@collect_time
def run():
    time.sleep(2)


if __name__ == '__main__':
    run()

简单说明:

  1. 上面中的在run函数上面添加@collect_time的写法, 相当于 collect_time(run)()
  2. collect_time(run)()意为将run函数的引用传递给collect_time函数, 然后运行collect_time(), 计算传入函数的运行时间

「登录鉴权装饰器 - demo示例」

代码语言:javascript
复制
def auth_user(func):
    def auth_count(**kwargs):
        username = kwargs["username"]
        password = kwargs["password"]
        if username == "lucy" and password == "12345":
            verify = True
        else:
            verify = False
        if verify:
            return {"code": 200, "data": func(username), "msg": "login succ"}
        else:
            return {"code": 403, "msg": "login fail"}

    return auth_count

@auth_user
def get_info(username="", password=""):
    return {"username": username, "login_time": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}


if __name__ == '__main__':
    # 正常用例
    print(get_info(username="lucy", password="12345"))
    
    # 错误用例
    # print(get_info(username="lucy", password="dfs"))

效果:

  • 输入正确的用户名 + 密码, 返回登录成功的响应信息, 例如:
代码语言:javascript
复制
{'code': 200, 'data': {'username': 'lucy', 'login_time': '2022-01-18 12:26:00'}, 'msg': 'login succ'}
  • 输入错误的用户名 or 密码, 返回登录失败的响应信息, 例如:
代码语言:javascript
复制
{"code": 403, "msg": "login fail"}

「代码详解 - 登录鉴权装饰器」

  1. 调用get_info(username="lucy", password="12345")时, 会将get_info这个函数引用当做参数传递给auth_user函数,返回auth_count的函数引用
  2. 随后会运行auth_count函数,该函数接收的参数为 username="lucy", password="12345"
  3. auth_count函数里面定义了一个字典形式的可变参数**kwargs, 然后从传入的参数中获取username 和 password
  4. auth_count函数内部根据解析的 username 和 password 来判断是否正确.如果正确就返回用户的登陆信息;错误的话,就返回403的error信息

以上就是今天关于装饰器的分享

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试开发卷货 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 闭包
  • 装饰器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档