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 18 Python
跟老齐学Python之有容乃大的list(4)
Sep 28 Python
用Python编写一个简单的Lisp解释器的教程
Apr 03 Python
讲解Python中运算符使用时的优先级
May 14 Python
Python 安装setuptools和pip工具操作方法(必看)
May 22 Python
Python中py文件引用另一个py文件变量的方法
Apr 29 Python
pandas DataFrame 根据多列的值做判断,生成新的列值实例
May 18 Python
python 统计文件中的字符串数目示例
Dec 24 Python
Pandas时间序列:重采样及频率转换方式
Dec 26 Python
Django静态资源部署404问题解决方案
May 11 Python
pytorch SENet实现案例
Jun 24 Python
Python进行区间取值案例讲解
Aug 02 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 UTF8编码内的繁简转换类
2009/07/20 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
php实现网页上一页下一页翻页过程详解
2019/06/28 PHP
php实现的简单多进程服务器类完整示例
2020/02/01 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
基于jquery的大众点评,分类导航实现代码
2011/08/23 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
js实现随屏幕滚动的带缓冲效果的右下角广告代码
2015/09/04 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
JavaScript实现带播放列表的音乐播放器实例分享
2016/03/07 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
vue2.0结合DataTable插件实现表格动态刷新的方法详解
2017/03/17 Javascript
js实现适配不同的屏幕大小
2017/04/10 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
使用Vue 实现滑动验证码功能
2019/06/27 Javascript
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
2019/10/23 Javascript
vue实现简单加法计算器
2020/10/22 Javascript
vue实现验证用户名是否可用
2021/01/20 Vue.js
Python中生成Epoch的方法
2017/04/26 Python
Python实现的堆排序算法原理与用法实例分析
2017/11/22 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
python celery分布式任务队列的使用详解
2019/07/08 Python
如何安装2019Pycharm最新版本(详细教程)
2019/09/26 Python
wxPython电子表格功能wx.grid实例教程
2019/11/19 Python
Python面向对象封装操作案例详解 II
2020/01/02 Python
医生进修自我鉴定
2014/01/19 职场文书
税务干部鉴定材料
2014/02/11 职场文书
会务接待方案
2014/02/27 职场文书
小区文明倡议书
2014/05/16 职场文书
银行求职信
2014/05/31 职场文书
个人批评与自我批评总结
2014/10/17 职场文书
趵突泉导游词
2015/02/03 职场文书
食品药品安全责任书
2015/05/11 职场文书