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自动化运维之IP地址处理模块详解
Dec 10 Python
Django admin实现图书管理系统菜鸟级教程完整实例
Dec 12 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
Apr 02 Python
Django 使用Ajax进行前后台交互的示例讲解
May 28 Python
python计算两个地址之间的距离方法
Jun 09 Python
利用python对Excel中的特定数据提取并写入新表的方法
Jun 14 Python
python元组和字典的内建函数实例详解
Oct 22 Python
python 图片二值化处理(处理后为纯黑白的图片)
Nov 01 Python
python 3.8.3 安装配置图文教程
May 21 Python
Python在线和离线安装第三方库的方法
Oct 31 Python
详解python polyscope库的安装和例程
Nov 13 Python
pytorch 如何使用batch训练lstm网络
May 28 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的urlencode()URL编码函数浅析
2011/08/09 PHP
使用Sphinx对索引进行搜索
2013/06/25 PHP
PHP_Cooikes不同页面无法传递的解决方法
2014/03/07 PHP
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
微信公众平台开发实现2048游戏的方法
2015/04/15 PHP
简明json介绍
2008/09/28 Javascript
原生js ActiveXObject获取execl里面的值
2013/11/01 Javascript
深入理解JQuery keyUp和keyDown的区别
2013/12/12 Javascript
javaScript 计算两个日期的天数相差(示例代码)
2013/12/27 Javascript
js/jQuery简单实现选项卡功能
2014/01/02 Javascript
jQuery validate验证插件使用详解
2016/05/11 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
百度搜索框智能提示案例jsonp
2016/11/28 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
2017/01/13 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
详解vue中多个有顺序要求的异步操作处理
2019/10/29 Javascript
解决微信授权成功后点击按返回键出现空白页和报错的问题
2020/06/08 Javascript
python动态性强类型用法实例
2015/05/09 Python
Python实现大文件排序的方法
2015/07/10 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
[原创]windows下Anaconda的安装与配置正解(Anaconda入门教程)
2018/04/05 Python
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
python实现ip地址查询经纬度定位详解
2019/08/30 Python
python 三种方法提取pdf中的图片
2021/02/07 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果
2021/01/27 HTML / CSS
英国马莎百货官网:Marks & Spencer
2016/07/29 全球购物
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
领导视察欢迎词
2014/01/15 职场文书
音乐教学反思
2014/02/02 职场文书
优秀党员个人总结
2015/02/14 职场文书
2015年乡镇妇联工作总结
2015/05/19 职场文书
如何在向量化NumPy数组上进行移动窗口
2021/05/18 Python