标签:call locker name 意义 should after 函数名 函数对象 turn
#函数装饰器即为不改变原函数代码的情况下为原函数添加额外功能。
1 #第一步,根据需求我们可以把原函数当初装饰函数的参数传进去,然后再执行原函数之前或之后添加需要的额外功能。 2 def deco(func): 3 print("before myfunc() called.") 4 func() 5 print(" after myfunc() called.") 6 return func 7 8 def myfunc(): 9 print(" myfunc() called.") 10 11 myfunc = deco(myfunc) 12 13 myfunc() 14 15 Result: 16 before myfunc() called. 17 myfunc() called. 18 after myfunc() called. 19 myfunc() called. 20 #我们发现原函数被执行了俩次,因为第一次是myfunc=deco(myfunc)的时候就已经执行了。后面我们调用的myfunc()其实是原函数又被调用了一次。
第二步,我们加上装饰器的语法糖@,可以达到同样的目的。
def deco(func): print("before myfunc() called.") func() print(" after myfunc() called.") return func @deco def myfunc(): print(" myfunc() called.") # myfunc = deco(myfunc) #等同于原函数上加上@deco myfunc() Result: before myfunc() called. myfunc() called. after myfunc() called. myfunc() called.
第三步,我们要解决@deco自动执行函数的问题,这样保证我们myfunc()调用的是装饰后的函数。
‘‘‘示例4: 使用内嵌包装函数来确保每次新函数都被调用, 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象‘‘‘ def deco(func): def _deco(): print("before myfunc() called.") func() print(" after myfunc() called.") # 不需要返回func,实际上应返回原函数的返回值 return _deco @deco def myfunc(): print(" myfunc() called.") myfunc() Result: before myfunc() called. myfunc() called. after myfunc() called.
好了。装饰器就这样产生了。下面我们示例带参数的和一些常用装饰器的用法。
‘‘‘示例1: 对带参数的函数进行装饰,
内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象‘‘‘
def deco(func):
def _deco(a, b):
print("before myfunc() called.")
ret = func(a, b)
print(" after myfunc() called. result: %s" % ret)
return ret
return _deco
@deco
def myfunc(a, b):
print(" myfunc(%s,%s) called." % (a, b))
return a + b
myfunc(1, 2)
myfunc(3, 4)
‘‘‘示例2: 在示例4的基础上,让装饰器带参数,
和上一示例相比在外层多了一层包装。
装饰函数名实际上应更有意义些‘‘‘
def deco(arg):
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, arg))
func()
print(" after %s called [%s]." % (func.__name__, arg))
return __deco
return _deco
@deco("mymodule")
def myfunc():
print(" myfunc() called.")
@deco("module2")
def myfunc2():
print(" myfunc2() called.")
myfunc()
myfunc2()
‘‘‘示例3: 装饰器带类参数‘‘‘
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()
myfunc()
标签:call locker name 意义 should after 函数名 函数对象 turn
原文地址:http://www.cnblogs.com/cyalu/p/6023486.html