Python的装饰器用法学习笔记


Posted in Python onJune 24, 2016

在python中常看到在定义函数是使用@func. 这就是装饰器, 装饰器是把一个函数作为参数的函数,常常用于扩展已有函数,即不改变当前函数状态下增加功能.

def run():
  print "I'm run."

我有这么一个函数, 我想知道这个函数什么时候开始什么时候结束. 我应该这么写

def run():
  print time.ctime()
  print "I'm run."
  print time.ctime()

但是如果不允许修改函数的话就需要装饰器了

def count(func):
  def wrapper():
    print time.ctime()
    ret = func()
    print time.ctime()
    return ret
  return wrapper

@count
def run():
  print "I'm run."

      # print '2015-4-10'

eg:

def now():
  print '2015-4-10'
f = now
f()

 

函数有一个__name__ 对象 可通过 dir(func) func为定义的函数名

now.__name__    # print 'now'
f.__name__     # print 'now'

print f       # print '<function now at 0x000000000213A908>'
print now      # print '<function now at 0x000000000213A908>'

我们通过装饰器打印log日志

def log(func):
  def wrapper(*args, **kwargs):
    print "call %s()" % func.__name__
    return func(*args, **kwargs)
  return wrapper

@log
def now():
  print '2015-4-10'

now()        # print 'call now()'

其实装饰器修饰函数相当于, now = log(now) 也就是装饰器函数把被修饰的函数当参数后赋给同名的变量

functools.wraps 函数

当我们使用了装饰器后now的__name__值发生了改变

# 没有使用前
now.__name__    # print 'now'
# 使用后
now.__name__    # print 'wrapper'

当我们使用装饰器前,now.__name__使用的是当前now函数,但使用后 now这个函数其实是 log(now) 也就是log函数的返回值也就是被包裹的wrapper. 解决方法是functools.wraps函数.

装饰闭包, 使用前得调用 import functools

def log(func):
  @functools.wraps(func)
  def wrapper(*args, **kwargs):
    ...

带参数的装饰器

如果decorator需要传入参数, 那就需要在写一个返回decorator的高阶函数. 写出来更复杂.

def login(level):
  def _deco(func):
    def wrapper(*args, **kwargs):
      if level >= 5:
        print '用户 VIP 等级 %d' % int(level-5)
      else:
        print '用户 ?潘 等级 %d' % abs(level-5)
      return func(*args, **kwargs)
    return wrapper
  return _deco

@login(5)
def user(username):
  print 'welcome, %s' % username

# 用户vip 等级0
# welcome, mink
user('mink')

带参数的decorator等于func = 装饰器函数(装饰器参数)(func)

装饰器类

通过类的__call__可以想使用函数一样使用类

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

  def __call__(self):
    return self.func() ** 2

@A
def foo():
  return 10

print foo()   # print 100
Python 相关文章推荐
Python 过滤字符串的技巧,map与itertools.imap
Sep 06 Python
探究数组排序提升Python程序的循环的运行效率的原因
Apr 01 Python
python实现自动发送邮件发送多人、群发、多附件的示例
Jan 23 Python
Ubuntu下使用python读取doc和docx文档的内容方法
May 08 Python
python实现批量解析邮件并下载附件
Jun 19 Python
python 字典 按key值大小 倒序取值的实例
Jul 06 Python
Python创建字典的八种方式
Feb 27 Python
python实现nao机器人手臂动作控制
Apr 29 Python
Python协程 yield与协程greenlet简单用法示例
Nov 22 Python
python实现udp传输图片功能
Mar 20 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
Aug 02 Python
python 如何利用argparse解析命令行参数
Sep 11 Python
Python的网络编程库Gevent的安装及使用技巧
Jun 24 #Python
深入解析Python编程中super关键字的用法
Jun 24 #Python
深入了解Python数据类型之列表
Jun 24 #Python
Python实现信用卡系统(支持购物、转账、存取钱)
Jun 24 #Python
Python提取Linux内核源代码的目录结构实现方法
Jun 24 #Python
Linux上安装Python的PIL和Pillow库处理图片的实例教程
Jun 23 #Python
尝试用最短的Python代码来实现服务器和代理服务器
Jun 23 #Python
You might like
PHP简洁函数(PHP简单明了函数语法)
2012/06/10 PHP
php自动给文章加关键词链接的函数代码
2012/11/29 PHP
PHP无法访问远程mysql的问题分析及解决
2013/05/16 PHP
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
浅析THINKPHP的addAll支持的最大数据量
2015/02/03 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
PHP实现动态添加XML中数据的方法
2018/03/30 PHP
jquery.boxy插件的iframe扩展代码
2010/07/02 Javascript
jQuery-Tools-overlay 使用介绍
2012/07/14 Javascript
JavaScript将相对地址转换为绝对地址示例代码
2013/07/19 Javascript
JS通过相同的name进行表格求和代码
2013/08/18 Javascript
jQuery实现行文字链接提示效果的方法
2015/03/10 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
详解Angular 4.x NgTemplateOutlet
2017/05/24 Javascript
jsonp跨域获取百度联想词的方法分析
2019/05/13 Javascript
基于better-scroll 实现歌词联动功能的代码
2020/05/07 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
Python探索之pLSA实现代码
2017/10/25 Python
Django学习教程之静态文件的调用详解
2018/05/08 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
使用python和pygame制作挡板弹球游戏
2019/12/03 Python
Pyecharts地图显示不完成问题解决方案
2020/05/11 Python
python中常用的数据结构介绍
2021/01/12 Python
Python3+PyCharm+Django+Django REST framework配置与简单开发教程
2021/02/16 Python
HTML5几个设计和修改的页面范例分享
2015/09/29 HTML / CSS
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
什么叫应用程序域?什么是托管代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
2012/05/23 面试题
个人思想理论学习的自我鉴定
2013/11/30 职场文书
产品销售员岗位职责
2013/12/18 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
2014乡镇党委副书记对照检查材料思想汇报
2014/10/09 职场文书
解除处分决定书
2015/06/25 职场文书
小学总务工作总结
2015/08/13 职场文书
2019年感恩励志演讲稿(收藏备用)
2019/09/11 职场文书
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server