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

时间:2022-09-19 07:40:55

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#! 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()

输出:

?
1
2
3
test start
in foo
end start

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

?
1
2
3
4
5
6
7
8
9
10
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')

输出:

?
1
2
3
4
>>>
test start
parameter_foo:hello
end start

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)

输出:

?
1
2
3
4
5
6
test start
a
end start
test start
1 2 3 4
end start

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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....')

输出:

?
1
2
3
4
5
in much_test
test start
one at:10
python....
end start
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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()

输出:

?
1
2
3
4
5
6
>>>
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
 myfunc() called.
locker.release() called.(不需要对象实例
>>>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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))

输出:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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程序设计有所帮助。