python函数装饰器用法实例详解


Posted in Python onJune 04, 2015

本文实例讲述了python函数装饰器用法。分享给大家供大家参考。具体如下:

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

#! coding=utf-8 
import time 
def timeit(func): 
  def wrapper(a): 
    start = time.clock() 
    func(1,2) 
    end =time.clock() 
    print 'used:', end - start 
    print a 
  return wrapper 
@timeit
# foo = timeit(foo)完全等价, 
# 使用之后,foo函数就变了,相当于是wrapper了 
def foo(a,b): 
  pass 
#不带参数的装饰器 
# wraper 将fn进行装饰,return wraper ,返回的wraper 就是装饰之后的fn 
def test(func): 
  def wraper(): 
    print "test start" 
    func() 
    print "end start" 
  return wraper 
@test 
def foo(): 
  print "in foo" 
foo()

输出:

test start 
in foo 
end start

装饰器修饰带参数的函数:

def parameter_test(func): 
  def wraper(a): 
    print "test start" 
    func(a) 
    print "end start" 
  return wraper 
@parameter_test 
def parameter_foo(a): 
  print "parameter_foo:"+a 
#parameter_foo('hello')

输出:

>>> 
test start 
parameter_foo:hello 
end start

装饰器修饰不确定参数个数的函数:

def much_test(func): 
  def wraper(*args, **kwargs): 
    print "test start" 
    func(*args, **kwargs) 
    print "end start" 
  return wraper 
@much_test 
def much1(a): 
  print a 
@much_test 
def much2(a,b,c,d ): 
  print a,b,c,d 
much1('a') 
much2(1,2,3,4)

输出:

test start 
a 
end start 
test start 
1 2 3 4 
end start

带参数的装饰器,再包一层就可以了:

def tp(name,age): 
  def much_test(func): 
    print 'in much_test' 
    def wraper(*args, **kwargs): 
      print "test start" 
      print str(name),'at:'+str(age) 
      func(*args, **kwargs) 
      print "end start" 
    return wraper 
  return much_test 
@tp('one','10') 
def tpTest(parameter): 
  print parameter 
tpTest('python....')

输出:

in much_test 
test start 
one at:10 
python.... 
end start
class locker: 
  def __init__(self): 
    print("locker.__init__() should be not called.") 
  @staticmethod 
  def acquire(): 
    print("locker.acquire() called.(这是静态方法)") 
  @staticmethod 
  def release(): 
    print("locker.release() called.(不需要对象实例") 
def deco(cls): 
  '''cls 必须实现acquire和release静态方法''' 
  def _deco(func): 
    def __deco(): 
      print("before %s called [%s]." % (func.__name__, cls)) 
      cls.acquire() 
      try: 
        return func() 
      finally: 
        cls.release() 
    return __deco 
  return _deco 
@deco(locker) 
def myfunc(): 
  print(" myfunc() called.") 
myfunc()

输出:

>>> 
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
 myfunc() called.
locker.release() called.(不需要对象实例
>>>
class mylocker: 
  def __init__(self): 
    print("mylocker.__init__() called.") 
  @staticmethod 
  def acquire(): 
    print("mylocker.acquire() called.") 
  @staticmethod 
  def unlock(): 
    print(" mylocker.unlock() called.") 
class lockerex(mylocker): 
  @staticmethod 
  def acquire(): 
    print("lockerex.acquire() called.") 
  @staticmethod 
  def unlock(): 
    print(" lockerex.unlock() called.") 
def lockhelper(cls): 
  '''cls 必须实现acquire和release静态方法''' 
  def _deco(func): 
    def __deco(*args, **kwargs): 
      print("before %s called." % func.__name__) 
      cls.acquire() 
      try: 
        return func(*args, **kwargs) 
      finally: 
        cls.unlock() 
    return __deco 
  return _deco 
class example: 
  @lockhelper(mylocker) 
  def myfunc(self): 
    print(" myfunc() called.") 
  @lockhelper(mylocker) 
  @lockhelper(lockerex) 
  def myfunc2(self, a, b): 
    print(" myfunc2() called.") 
    return a + b 
if __name__=="__main__": 
  a = example() 
  a.myfunc() 
  print(a.myfunc()) 
  print(a.myfunc2(1, 2)) 
  print(a.myfunc2(3, 4))

输出:

before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
None
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
3
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
7

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
解析Python中while true的使用
Oct 13 Python
Python之父谈Python的未来形式
Jul 01 Python
Python中操作mysql的pymysql模块详解
Sep 13 Python
pycharm+django创建一个搜索网页实例代码
Jan 24 Python
pandas 选择某几列的方法
Jul 03 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
Apr 29 Python
如何使用Python自动控制windows桌面
Jul 11 Python
python3文件复制、延迟文件复制任务的实现方法
Sep 02 Python
python实现将一维列表转换为多维列表(numpy+reshape)
Nov 29 Python
python 装饰器的使用示例
Oct 10 Python
浅析python中特殊文件和特殊函数
Feb 24 Python
Python中函数的参数定义和可变参数用法实例分析
Jun 04 #Python
python类装饰器用法实例
Jun 04 #Python
python获得一个月有多少天的方法
Jun 04 #Python
Python中threading模块join函数用法实例分析
Jun 04 #Python
django通过ajax发起请求返回JSON格式数据的方法
Jun 04 #Python
python创建进程fork用法
Jun 04 #Python
Python文件及目录操作实例详解
Jun 04 #Python
You might like
如何在PHP中使用Oracle数据库(5)
2006/10/09 PHP
使用PHP函数scandir排除特定目录
2014/06/12 PHP
基于Laravel5.4实现多字段登录功能方法示例
2017/08/11 PHP
Javascript 判断Flash是否加载完成的代码
2010/04/12 Javascript
在JS数组特定索引处指定位置插入元素
2014/07/27 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
JavaScript 冒泡排序和选择排序的实现代码
2016/09/03 Javascript
JavaScript中全选、全不选、反选、无刷新删除、批量删除、即点即改入库(在yii框架中操作)的代码分享
2016/11/01 Javascript
js/jq仿window文件夹移动/剪切/复制等操作代码
2017/03/08 Javascript
vue+axios新手实践实现登陆的示例代码
2018/06/06 Javascript
解决vue keep-alive 数据更新的问题
2018/09/21 Javascript
jquery获取file表单选择文件的路径、名字、大小、类型
2019/01/18 jQuery
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
Vue实现多页签组件
2021/01/14 Vue.js
Python set集合类型操作总结
2014/11/07 Python
使用Python标准库中的wave模块绘制乐谱的简单教程
2015/03/30 Python
python中lambda与def用法对比实例分析
2015/04/30 Python
Python编程入门的一些基本知识
2015/05/13 Python
python实现文本文件合并
2015/12/29 Python
CentOS 6.X系统下升级Python2.6到Python2.7 的方法
2016/10/12 Python
如何高效使用Python字典的方法详解
2017/08/31 Python
详解Python核心编程中的浅拷贝与深拷贝
2018/01/07 Python
Python numpy 提取矩阵的某一行或某一列的实例
2018/04/03 Python
django表单的Widgets使用详解
2019/07/22 Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
2020/02/29 Python
Python telnet登陆功能实现代码
2020/04/16 Python
Python 通过正则表达式快速获取电影的下载地址
2020/08/17 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
2020/09/23 Python
HTML5触摸事件实现移动端简易进度条的实现方法
2018/05/04 HTML / CSS
怎样在程序里获得一个空指针
2015/01/24 面试题
幼儿师范毕业生自荐信
2013/11/09 职场文书
工作态度检讨书
2014/02/11 职场文书
公司中秋节活动方案
2014/02/12 职场文书
《飞向蓝天的恐龙》教学反思
2014/04/09 职场文书
安全口号大全
2014/06/21 职场文书
使用scrapy实现增量式爬取方式
2022/06/21 Python