文档章节

Python装饰器学习笔记

nightwing
 nightwing
发布于 2015/05/31 13:26
字数 993
阅读 21
收藏 0

之前在看<<Python核心编程>>时遇到decorator时看得云里雾里,然后也没去多管,想到等以后遇到这个问题 时再去解决。今天在看Django代码时看到login_required等装饰器时又遇到这个东西了,于是在网上找了一些文档重新学了一下,在此做一个 总结。


1. 装饰器含义

装 饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器, 我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。



2. 装饰器语法

(1)无参数装饰器

  1. def deco(func):  

  2.     print("deco")  

  3.     return func  

  4.  

  5. @deco   

  6. def foo():  

  7.     print("foo")  

  8.   

  9. foo()  

第一个函数deco是装饰函数,它的参数就是被装饰的函数对象。我们可以在deco函数内对传入的函数对象做一番“装饰”,然后返回这个对象(记住一定要返回 ,不然外面调用foo的地方将会无函数可用。实际上此时foo=deco(foo)


(2)有参数装饰器

被装饰函数无参数

  1. def deco(argv):  

  2.     def decorator(func):  

  3.         print("decorator")  

  4.         return func  

  5.     print("deco")  

  6.     print(argv)  

  7.     return decorator  

  8.  

  9. @deco ("123")  

  10. def foo():  

  11.     print("foo")  

  12.   

  13. foo()  

第一个函数deco是装饰函数,它的参数是用来“加强装饰”的。由于此函数并非被装饰的函数对象,所以在内部必须至少创建一个接受被装饰函数的函数,然后返回这个对象。实际上此时foo = deco(argv)(foo)

被装饰函数也有参数

  1. from functools import wraps  

  2.   

  3. def deco(argv):  

  4.     def decorator(func):  

  5.         @wraps(func)  

  6.         def wrapper(*args, **kwargs):  

  7.             print("wrapper")  

  8.             return func(*args, **kwargs)  

  9.         print("decorator")  

  10.         return wrapper  

  11.     print("deco")  

  12.     print(argv)  

  13.     return decorator  

  14.  

  15. @deco ("123")  

  16. def foo(data):  

  17.     "this is foo"  

  18.     print("foo")  

  19.     print(data)  

  20.   

  21. foo("afdasdf")  

  22.   

  23. print(foo.__name__, foo.__doc__)  

在decorator函数内部还需要定义一个函数来接受被装饰函数的参数。此时foo = deco(argv)(foo)(data)

首 先注意第5行,如果注释这一行,foo.__name__将是'wrapper',使用这个装饰器后装饰之后的foo.__name__将还是原来的 foo,wraps装饰器是将func的常用属性赋给了wrapper函数。另外相信你也注意到了,这个装饰器竟然带有一个参数。实际上,他还有另外两个 可选的参数,assigned中的属性名将使用赋值的方式替换,而updated中的属性名将使用update的方式合并,你可以通过查看 functools的源代码获得它们的默认值。对于这个装饰器,相当于wrapper = functools.wraps(func)(wrapper)


(3)多装饰器组合使用

  1. def deco1(func):  

  2.     print("deco1")  

  3.     return func  

  4.   

  5. def deco2(func):  

  6.     print("deco2")  

  7.     return func  

  8.  

  9. @deco2  

  10. @deco1  

  11. def foo():  

  12.     print("foo")  

  13.   

  14. foo()  

注意多个装饰器的执行顺序,应该是先执行下面的,然后是上面的。这里应先执行deco1,然后是deco2。


(4)例子

  1. def makebold(func):  

  2.     def wrapped():  

  3.         return "<b>" + func() + "</b>"  

  4.     return wrapped  

  5.   

  6. def makeitalic(func):  

  7.     def wrapped():  

  8.         return "<i>" + func() + "</i>"  

  9.     return wrapped  

  10.  

  11. @makebold  

  12. @makeitalic  

  13. def say():  

  14.     return "Hello"  

  15.   

  16. print(say())  

  1. #output  

  2. ''''' 

  3. <b><i>Hello</i></b> 

  4. '''  



3. 体会

当多个函数有重复代码时可以将此部分代码单独拿出来整理成一个装饰器,然后对每个函数调用该装饰器,这样可以实现代码的复用,而且可以让原来的函数更轻便。

还有就是当我们需要为多个已经写好的函数添加一个共同功能,比如检查参数的合法性。我们就可以单独写一个检查合法性的装饰器,然后在每个需要检查参数合法性的函数出调用即可,而不用去每个函数内部修改。


本文转载自:http://blog.csdn.net/wangtaoking1/article/details/20565131

上一篇: HTML 速查列表
下一篇: PyQt4学习
nightwing
粉丝 0
博文 19
码字总数 1833
作品 0
朝阳
私信 提问
python 面向对象高级编程之使用@property

python学习笔记,特做记录,分享给大家,希望对大家有所帮助。 使用@property 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:...

展菲
07/07
0
0
编程学习笔记之python深入之装饰器案例及说明文档[图]

编程学习笔记之python深入之装饰器案例及说明文档[图] 装饰器即在不对一个函数体进行任何修改,以及不改变整体的原本意思的情况下,增加函数功能的新函数,因为这个新函数对旧函数进行了装饰...

原创小博客
2018/07/22
9
0
python 装饰器及标准库functools中的wraps

最近在看 flask的视图装饰器 时,忽然想起预(复)习一下python的装饰器. 这里有一篇比较好的讲解装饰器的书写的 Python装饰器学习(九步入门) . 这里不单独记录装饰器的书写格式了,重点是工作...

L很失败L
2015/08/20
925
0
python 函数式编程之装饰器

python学习笔记,特做记录,分享给大家,希望对大家有所帮助。 装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。 运行结果: 函数对象有一个nam...

展菲
06/29
0
0
Python3基础之学习笔记(五)-装饰器-迭代器和生成器-内置函数

文章目录 1.装饰器 2.迭代器与生成器 3.迭代器 4.内置函数 1.装饰器 1.1装饰器简介 装饰器本质是函数,是用来装饰其他函数的,为其他函数添加附件功能 原则: 不能修改被装饰的函数的源代码 ...

GoldenKitten
01/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 ——不知道假装开心,装的像么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 :天黑了 你很忧愁, 你说世界上, 找不到四块五的妞, 行走在凌晨两点的马路上, 你疲倦地拿着半盒黄鹤楼。#今日歌曲推荐# 《四块...

小小编辑
今天
2.1K
16
64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
昨天
69
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
昨天
32
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
昨天
116
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
昨天
31
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部