如何正确理解python装饰器


Posted in Python onJune 15, 2021

一、闭包

要想了解装饰器,首先要了解一个概念,闭包。什么是闭包,一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包了。光说没有概念,直接上一个例子。

def outer(x):
    def inner(y):
        return x + y
    return inner

print(outer(6)(5))
-----------------------------
>>>11

如代码所示,在outer函数内,又定义了一个inner函数,并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。

二、装饰器

接下来就讲装饰器,其实装饰器就是一个闭包,装饰器是闭包的一种应用。什么是装饰器呢,简言之,python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。使用时,再需要的函数前加上@demo即可。

def debug(func):
    def wrapper():
        print("[DEBUG]: enter {}()".format(func.__name__))
        return func()
    return wrapper

@debug
def hello():
    print("hello")

hello()
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello

例子中的装饰器给函数加上一个进入函数的debug模式,不用修改原函数代码就完成了这个功能,可以说是很方便了。

三、带参数的装饰器

上面例子中的装饰器是不是功能太简单了,那么装饰器可以加一些参数吗,当然是可以的,另外装饰的函数当然也是可以传参数的。

def logging(level):
    def outwrapper(func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
    return outwrapper

@logging(level="INFO")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[INFO]: enter hello()
>>>hello, good morning

如上,装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也是可以的,用不定长参数符号就可以接收,例子中传入了三个参数。

四、类装饰器

装饰器也不一定只能用函数来写,也可以使用类装饰器,用法与函数装饰器并没有太大区别,实质是使用了类方法中的__call__魔法方法来实现类的直接调用。

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

    def __call__(self, *args, **kwargs):
        print("[DEBUG]: enter {}()".format(self.func.__name__))
        return self.func(*args, **kwargs)

@logging
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[DEBUG]: enter hello()
>>>hello, good morning

类装饰器也是可以带参数的,如下实现

class logging(object):
    def __init__(self, level):
        self.level = level

    def __call__(self, func):
        def wrapper(*args, **kwargs):
            print("[{0}]: enter {1}()".format(self.level, func.__name__))
            return func(*args, **kwargs)
        return wrapper
        
@logging(level="TEST")
def hello(a, b, c):
    print(a, b, c)

hello("hello,","good","morning")
-----------------------------
>>>[TEST]: enter hello()
>>>hello, good morning

好了,如上就是装饰器的一些概念和大致的用法啦,想更深入的了解装饰器还是需要自己在平时的练习和应用中多体会

以上就是如何正确理解python装饰器的详细内容,更多关于python装饰器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python heapq使用详解及实例代码
Jan 25 Python
django传值给模板, 再用JS接收并进行操作的实例
May 28 Python
python编辑用户登入界面的实现代码
Jul 16 Python
有关Python的22个编程技巧
Aug 29 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
Jan 04 Python
python实现简单飞行棋
Feb 06 Python
Python2与Python3的区别详解
Feb 09 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
Apr 23 Python
python基于socket函数实现端口扫描
May 28 Python
pytorch随机采样操作SubsetRandomSampler()
Jul 07 Python
用python给csv里的数据排序的具体代码
Jul 17 Python
python+appium+yaml移动端自动化测试框架实现详解
Nov 24 Python
详解python网络进程
整理Python中常用的conda命令操作
Python实现单例模式的5种方法
Jun 15 #Python
用Python爬取某乎手机APP数据
七个非常实用的Python工具包总结
python异常中else的实例用法
Jun 15 #Python
Python实现简单的猜单词
You might like
PHP定时执行计划任务的多种方法小结
2011/12/19 PHP
PHP中is_file不能替代file_exists的理由
2014/03/04 PHP
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
CodeIgniter框架实现的整合Smarty引擎DEMO示例
2019/03/28 PHP
Mootools 1.2教程 事件处理
2009/09/15 Javascript
整理一些JavaScript的IE和火狐的兼容性注意事项
2011/03/17 Javascript
javascript scrollTop正解使用方法
2013/11/14 Javascript
JavaScript立即执行函数的三种不同写法
2014/09/05 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
2015/08/13 Javascript
js实现当复选框选择匿名登录时隐藏登录框效果
2015/08/14 Javascript
早该知道的7个JavaScript技巧
2016/06/21 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
2016/09/04 Javascript
xmlplus组件设计系列之列表(4)
2017/04/26 Javascript
Angularjs使用过滤器完成排序功能
2017/09/20 Javascript
使用cookie绕过验证码登录的实现代码
2017/10/12 Javascript
微信小程序顶部导航栏滑动tab效果
2019/01/28 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
vue在线动态切换主题色方案
2020/03/26 Javascript
JavaScript鼠标悬停事件用法解析
2020/05/15 Javascript
浅谈js中的attributes和Attribute的用法与区别
2020/07/16 Javascript
python抓取网页图片并放到指定文件夹
2014/04/24 Python
python编写网页爬虫脚本并实现APScheduler调度
2014/07/28 Python
Python中暂存上传图片的方法
2015/02/18 Python
Django保护敏感信息的方法示例
2019/05/09 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
python实现超市商品销售管理系统
2019/11/22 Python
python让函数不返回结果的方法
2020/06/22 Python
惠普墨西哥官方商店:HP墨西哥
2016/12/01 全球购物
美国最大和最受信任的二手轮胎商店:Bestusedtires.com
2020/06/02 全球购物
如何向接受结构参数的函数传入常数值
2016/02/17 面试题
各营销点岗位职责范本
2014/03/05 职场文书
超市开店计划书
2014/04/26 职场文书
班级年度安全计划书
2014/05/01 职场文书
新文化运动的基本口号
2014/06/21 职场文书
党的群众路线教育实践活动整改落实情况自查报告
2014/10/28 职场文书
安全责任书
2015/01/29 职场文书