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中去空格函数的用法
Aug 21 Python
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
Feb 18 Python
python二分查找算法的递归实现方法
May 12 Python
Python 如何访问外围作用域中的变量
Sep 11 Python
python+opencv轮廓检测代码解析
Jan 05 Python
python3 拼接字符串的7种方法
Sep 12 Python
python实现播放音频和录音功能示例代码
Dec 30 Python
Python利用sqlacodegen自动生成ORM实体类示例
Jun 04 Python
解决django中ModelForm多表单组合的问题
Jul 18 Python
python如何通过闭包实现计算器的功能
Feb 22 Python
python openCV自制绘画板
Oct 27 Python
解析python中的jsonpath 提取器
Jan 18 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中如何将数组变量写入文件
2013/06/06 PHP
用Div仿showModalDialog模式菜单的效果的代码
2007/03/05 Javascript
解析Javascript中大括号“{}”的多义性
2013/12/02 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
在JavaScript的正则表达式中使用exec()方法
2015/06/16 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
手机端转盘抽奖代码分享
2015/09/10 Javascript
jquery 获取select数组与name数组长度的实现代码
2016/06/20 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
深入理解基于vue-cli的vuex配置
2017/07/24 Javascript
一个基于react的图片裁剪组件示例
2018/04/18 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
2018/05/25 Javascript
详解.vue文件解析的实现
2018/06/11 Javascript
微信小程序 swiper 组件遇到的问题及解决方法
2019/05/26 Javascript
用python实现批量重命名文件的代码
2012/05/25 Python
RC4文件加密的python实现方法
2015/06/30 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
2018/08/10 Python
对python指数、幂数拟合curve_fit详解
2018/12/29 Python
浅谈python 中类属性共享的问题
2019/07/02 Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
2019/08/13 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
Tensorflow tensor 数学运算和逻辑运算方式
2020/06/30 Python
英国儿童家具专卖店:GLTC
2016/09/24 全球购物
历史学专业大学生找工作的自我评价
2013/10/16 职场文书
文秘自荐信
2014/06/28 职场文书
实验心得体会
2014/09/05 职场文书
街道党工委党的群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
开会迟到检讨书范文
2015/05/06 职场文书
欢送会主持词
2015/07/01 职场文书
同步小康驻村工作简报
2015/07/20 职场文书
学校食堂管理制度
2015/08/04 职场文书
安全教育培训制度
2015/08/06 职场文书
奖学金申请个人主要事迹材料
2015/11/04 职场文书
2016教师校本培训心得体会
2016/01/08 职场文书
详细介绍python类及类的用法
2021/05/31 Python