python装饰器代码解析


Posted in Python onMarch 23, 2022

1.装饰器通用模型

def wrapper(fn):
    def inner(*args, **kwargs):
        ret = fn(*args, **kwargs)
        return ret

    return inner

装饰器几个关键点:

  • 1.函数可以当参数传递
  • 2.函数可以作为返回值进行返回
  • 3.函数名称可以当成变量一样进行赋值操作

装饰器本质上是个闭包,在不改变原有函数调用的情况下,给函数增加新的功能

举个例子:

def admin(game):
    def inner(*args, **kwargs):  # inner添加了参数,args 一定是个元组 kwargs 一定是字典
        print('打开Wg')
        result = game(*args, **kwargs)  # * ** 表示把args元组和kwargs打散成位置参数,关键字参数传递进去
        print('关闭Wg')
        return result

    return inner


@admin
def play_dnf(username, password):
    print(f'开始玩DNF,账号:{username},密码:{password}')
    print('刀斩肉身,心斩灵魂')
    return '掉落:戮蛊的哀鸣炮'


@admin
def play_wow(race, occupation, server_name, camp):
    print(f'开始玩魔兽世界,种族:{race},职业:{occupation},服务器:{server_name},阵营:{camp}')
    print('为了辛多雷的荣耀')
    return '掉落:灰烬使者'


if __name__ == '__main__':
    ret1 = play_dnf('大马猴', '888888')
    print(ret1)
    ret2 = play_wow('血精灵', '圣骑士', '回音山', '部落')
    print(ret2)

这代码还是很好懂的,我就不解释了,然后是执行结果如下:

python demo.py
打开Wg
开始玩DNF,账号:大马猴,密码:888888
刀斩肉身,心斩灵魂
关闭Wg
掉落:戮蛊的哀鸣炮
打开Wg
开始玩魔兽世界,种族:血精灵,职业:圣骑士,服务器:回音山,阵营:部落
为了辛多雷的荣耀
关闭Wg
掉落:灰烬使者

Process finished with exit code 0

2.多个装饰器装饰的函数执行

一个函数被多个装饰器装饰,又将如何执行呢?

def wrapper1(fn):
    def inner(*args, **kwargs):
        print('这是w1进入')
        ret = fn(*args, **kwargs)
        print('这是w1出去')
        return ret

    return inner


def wrapper2(fn):
    def inner(*args, **kwargs):
        print('这是w2进入')
        ret = fn(*args, **kwargs)
        print('这是w2出去')
        return ret

    return inner


@wrapper1
@wrapper2
def target():
    print('我是目标')


if __name__ == '__main__':
    target()

直接给出执行顺序:

一个函数被多个装饰器装饰的执行顺序

# w1 w2 target w2 w1

3.带参数的装饰器

装饰器的语法允许我们在调用时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。
(在上面又套了一层函数)
比如,我们可以在装饰器中指定日志的等级,因为不同业务函数可能需要的日志级别是不一样的。

def use_logging(level):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if level == "warn":
                logging.warn("%s is running" % func.__name__)
            elif level == "info":
                logging.info("%s is running" % func.__name__)
            return func(*args)
        return wrapper

    return decorator

@use_logging(level="warn")
def foo(name='foo'):
    print("i am %s" % name)

foo()

4.类装饰器

没错,装饰器不仅可以是函数,还可以是类,相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器主要依靠类的__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。

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

    def __call__(self):
        print ('class decorator runing')
        self._func()
        print ('class decorator ending')

@Foo
def bar():
    print ('bar')

bar()

到此这篇关于python装饰器代码解析的文章就介绍到这了,更多相关python装饰器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python爬豆瓣电影实例
Feb 23 Python
python中的for循环
Sep 28 Python
对python 操作solr索引数据的实例详解
Dec 07 Python
解决Python中定时任务线程无法自动退出的问题
Feb 18 Python
PyQt5 QTableView设置某一列不可编辑的方法
Jun 25 Python
Python Django 添加首页尾页上一页下一页代码实例
Aug 21 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
Mar 12 Python
Python3 中sorted() 函数的用法
Mar 24 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
Nov 17 Python
Python性能测试工具Locust安装及使用
Dec 01 Python
Python实现信息轰炸工具(再也不怕说不过别人了)
Jun 11 Python
Python面向对象编程之类的概念
Nov 01 Python
基于Python实现将列表数据生成折线图
Python必备技巧之字符数据操作详解
Pytorch中使用ImageFolder读取数据集时忽略特定文件
Mar 23 #Python
Python借助with语句实现代码段只执行有限次
Mar 23 #Python
python3 字符串str和bytes相互转换
Mar 23 #Python
对象析构函数__del__在Python中何时使用
详解Python内置模块Collections
Mar 22 #Python
You might like
PHP实现微信退款的方法示例
2019/03/26 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
jQuery1.6 使用方法一
2011/11/23 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
2014/09/01 Javascript
JavaScript创建一个object对象并操作对象属性的用法
2015/03/23 Javascript
JS图片压缩(pc端和移动端都适用)
2017/01/12 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
基于vue组件实现猜数字游戏
2020/05/28 Javascript
浅谈vuepress 踩坑记
2018/04/18 Javascript
12个提高JavaScript技能的概念(小结)
2019/05/09 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
[16:21]教你分分钟做大人:圣堂刺客
2014/12/03 DOTA
[01:38]2018DOTA2亚洲邀请赛主赛事第二日现场采访 神秘商人痛陈生计不易
2018/04/05 DOTA
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
浅谈Python的文件类型
2016/05/30 Python
Python探索之pLSA实现代码
2017/10/25 Python
python写入文件自动换行问题的方法
2019/07/05 Python
Django的models模型的具体使用
2019/07/15 Python
Django CBV类的用法详解
2019/07/26 Python
详解HTML5中的拖放事件(Drag 和 drop)
2016/11/14 HTML / CSS
师范生自我鉴定范文
2013/10/05 职场文书
外贸业务员工作职责
2014/01/06 职场文书
中学运动会广播稿
2014/01/19 职场文书
促销活动总结
2014/04/28 职场文书
社会调查研究计划书
2014/05/01 职场文书
物理学专业求职信
2014/07/04 职场文书
2014年社区重阳节活动策划方案
2014/09/16 职场文书
小学音乐教师个人工作总结
2015/02/05 职场文书
综合素质评价个性与发展自我评价
2015/03/06 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
2016年保险公众宣传日活动总结
2016/04/05 职场文书
原来实习报告是这样写的呀!
2019/07/03 职场文书
小学语文教师竞聘演讲稿范文
2019/08/09 职场文书
深入浅析Django MTV模式
2021/09/04 Python
JavaScript流程控制(分支)
2021/12/06 Javascript
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL