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

作者:MaxOmnis 时间:2023-09-23 09:40:16 

本文实例讲述了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,函数,装饰器
0
投稿

猜你喜欢

  • FileSystem对象常用的文件操作函数有哪些?

    2009-11-01 15:11:00
  • Django crontab定时任务模块操作方法解析

    2022-08-01 03:50:56
  • 记录模型训练时loss值的变化情况

    2022-03-22 23:39:48
  • Numpy实现卷积神经网络(CNN)的示例

    2022-10-06 17:44:17
  • MySQL表的重命名字段添加及字段属性修改操作语法

    2024-01-21 07:18:35
  • Django使用HTTP协议向服务器传参方式小结

    2023-03-08 11:31:20
  • mysql建表常用sql语句个人经验分享

    2024-01-27 12:30:48
  • JavaScript中用getDate()方法返回指定日期的教程

    2024-05-09 09:05:46
  • PyCharm取消波浪线、下划线和中划线的实现

    2021-11-27 02:17:27
  • Python可视化神器pyecharts绘制仪表盘

    2021-12-29 15:57:53
  • Python+Pyecharts实现散点图的绘制

    2023-09-02 05:01:29
  • python实现简单socket程序在两台电脑之间传输消息的方法

    2021-04-25 21:14:26
  • Numpy数据类型转换astype,dtype的方法

    2021-02-15 00:58:14
  • 轻松掌握python设计模式之策略模式

    2022-01-19 00:17:15
  • python 异常的传递性及主动抛出学习

    2021-03-19 05:02:38
  • python中get和post有什么区别

    2022-04-17 16:45:15
  • Python采集王者皮肤图片实战示例

    2021-08-02 12:09:23
  • 悟道Web标准:让W3C标准兼容终端

    2009-10-11 16:40:00
  • 如何使用python批量修改文本文件编码格式

    2021-02-15 14:01:30
  • python初学者,用python实现基本的学生管理系统(python3)代码实例

    2023-07-01 11:40:01
  • asp之家 网络编程 m.aspxhome.com