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 获取本机ip地址的两个方法
Feb 25 Python
研究Python的ORM框架中的SQLAlchemy库的映射关系
Apr 25 Python
Python列表list内建函数用法实例分析【insert、remove、index、pop等】
Jul 24 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
Jan 04 Python
聊聊python里如何用Borg pattern实现的单例模式
Jun 06 Python
python实现TCP文件传输
Mar 20 Python
TensorFlow keras卷积神经网络 添加L2正则化方式
May 22 Python
Python SMTP配置参数并发送邮件
Jun 16 Python
Python 整行读取文本方法并去掉readlines换行\n操作
Sep 03 Python
使用gunicorn部署django项目的问题
Dec 30 Python
Spy++的使用方法及下载教程
Jan 29 Python
Python的Tqdm模块实现进度条配置
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
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
2014/06/12 PHP
在WordPress中获取数据库字段内容和添加主题设置菜单
2016/01/11 PHP
PHP递归算法的简单实例
2019/02/28 PHP
多个iframe自动调整大小的问题
2006/09/18 Javascript
Javascript的一种模块模式
2010/09/08 Javascript
from 表单提交返回值用post或者是get方法实现
2013/08/21 Javascript
javascript中的if语句使用介绍
2013/11/20 Javascript
Jquery实现自定义tooltip示例代码
2014/02/12 Javascript
javascript 获取函数形参个数
2014/07/31 Javascript
使用JSON.parse将json字符串转换成json对象的时候会出错
2014/09/04 Javascript
微信小程序实现图片预加载组件
2017/01/18 Javascript
轻松理解JavaScript闭包
2017/03/14 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
Node层模拟实现multipart表单的文件上传示例
2018/01/02 Javascript
js canvas实现红包照片效果
2018/08/21 Javascript
node全局变量__dirname与__filename的区别
2019/01/14 Javascript
react配置antd按需加载的使用
2019/02/11 Javascript
React 父子组件通信的实现方法
2019/12/05 Javascript
Python中的对象,方法,类,实例,函数用法分析
2015/01/15 Python
Python使用xlrd读取Excel格式文件的方法
2015/03/10 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
2015/05/29 Python
Python中格式化format()方法详解
2017/04/01 Python
python在新的图片窗口显示图片(图像)的方法
2019/07/11 Python
Django 请求Request的具体使用方法
2019/11/11 Python
python opencv把一张图片嵌入(叠加)到另一张图片上的实现代码
2020/06/11 Python
python requests库的使用
2021/01/06 Python
详解CSS3中的box-sizing(content-box与border-box)
2019/04/19 HTML / CSS
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
CSMA/CD介质访问控制协议
2015/11/17 面试题
护理学毕业生自荐信
2013/10/02 职场文书
四风批评与自我批评范文
2014/10/14 职场文书
房产协议书范本
2014/10/18 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书
《孙子兵法》:欲成大事者,需读懂这些致胜策略
2019/08/23 职场文书
集英社今正式宣布 成立游戏公司“集英社Games”
2022/03/31 其他游戏
Go Grpc Gateway兼容HTTP协议文档自动生成网关
2022/06/16 Golang