python装饰器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python装饰器相关的知识,希望对你有一定的参考价值。
#函数装饰器即为不改变原函数代码的情况下为原函数添加额外功能。
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()
以上是关于python装饰器的主要内容,如果未能解决你的问题,请参考以下文章