如何正确理解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进阶教程之词典、字典、dict
Aug 29 Python
python实现画圆功能
Jan 25 Python
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
Apr 28 Python
python获取指定字符串中重复模式最高的字符串方法
Jun 29 Python
OpenCV2从摄像头获取帧并写入视频文件的方法
Aug 03 Python
python实现图片二值化及灰度处理方式
Dec 07 Python
基于pytorch的lstm参数使用详解
Jan 14 Python
Python中私有属性的定义方式
Mar 05 Python
学习python需要有编程基础吗
Jun 02 Python
Keras之fit_generator与train_on_batch用法
Jun 17 Python
python中sqllite插入numpy数组到数据库的实现方法
Jun 21 Python
Pyqt5将多个类组合在一个界面显示的完整示例
Sep 04 Python
详解python网络进程
整理Python中常用的conda命令操作
Python实现单例模式的5种方法
Jun 15 #Python
用Python爬取某乎手机APP数据
七个非常实用的Python工具包总结
python异常中else的实例用法
Jun 15 #Python
Python实现简单的猜单词
You might like
PHP使用curl制作简易百度搜索
2016/11/03 PHP
TP5(thinkPHP框架)实现后台清除缓存功能示例
2019/05/29 PHP
理解JSON:3分钟课程
2011/10/28 Javascript
javascript的alert box在java中如何显示多行
2014/05/18 Javascript
Jquery实现图片预加载与延时加载的方法
2014/12/22 Javascript
jquery 中ajax执行的优先级
2015/06/22 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
轻松实现jquery手风琴效果
2016/01/14 Javascript
AngularJS手动表单验证
2016/02/01 Javascript
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
vue的全局提示框组件实例代码
2018/02/26 Javascript
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
2018/08/17 Javascript
vue下history模式刷新后404错误解决方法
2018/08/18 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
node.js中module模块的功能理解与用法实例分析
2020/02/14 Javascript
node.js如何根据URL返回指定的图片详解
2020/10/21 Javascript
[47:03]Ti4第二日主赛事败者组 LGD vs iG 2
2014/07/21 DOTA
[00:32]2018DOTA2亚洲邀请赛VG出场
2018/04/03 DOTA
使用python BeautifulSoup库抓取58手机维修信息
2013/11/21 Python
python输出当前目录下index.html文件路径的方法
2015/04/28 Python
Python实用日期时间处理方法汇总
2015/05/09 Python
浅谈python新手中常见的疑惑及解答
2016/06/14 Python
浅谈Python里面小数点精度的控制
2018/07/16 Python
python实现彩票系统
2020/06/28 Python
12个步骤教你理解Python装饰器
2019/07/01 Python
wxpython布局的实现方法
2019/11/01 Python
python 使用cx-freeze打包程序的实现
2020/03/14 Python
python 最简单的实现适配器设计模式的示例
2020/06/30 Python
详解CSS3选择器:nth-child和:nth-of-type之间的差异
2017/09/18 HTML / CSS
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
迎八一活动主题
2014/01/31 职场文书
作风大整顿心得体会
2014/09/10 职场文书
超市主管竞聘书
2015/09/15 职场文书
安全生产学习心得体会
2016/01/18 职场文书
2016年党员学习廉政准则心得体会
2016/01/20 职场文书