第一步:(简单的函数调用)
def myfunc()
print('myfunc() called.")
myfunc()
第二步:(修饰器本质的调用原理,修饰器内调用被修饰的函数)
def deco(func):
print('before myfunc() called.') func() print('after myfunc() called')def myfunc(): print('myfunc() called')myfunc=deco(myfunc)#最重要的一步,修饰器就是一个函数,一个容器,用来放进其他函数修饰,改变,在函数前后添加内容的
第三步:最简单的修饰器(相当于“myfunc = deco(myfunc)”)
def deco(func):
print('before myfunc() called.') func() print('after myfunc() called.') return func@decodef myfunc(): print('myfunc() called')
第四步:内嵌包装函数(保护函数)
def deco(func):
def _deco(): print('before myfunc() called.') func() print('after myfunc() called.') return _deco@decodef myfunc(): print('myfunc() called')myfunc()
第五步:被修饰的函数有参数
修饰器第二层函数需要有被修饰函数的参数,并且第二层返回被修饰函数运行后的值,被修饰函数也要返回值
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@decodef myfunc(a,b): print('myfunc(%s,%s) called.' % (a,b)) return a+bmyfunc(1,2)
第六步:被修饰的函数不确定数量(使用*args,**kwargs)
def deco(func):
def _deco(*args,**kwargs): print('before %s called.' % func.__name__) ret=func(*args,**kwargs) print('after %s called. result:%s' % (func.__name__,ret)) return ret return _deco@decodef myfunc(a,b): print('myfunc(%s,%s) called.' % (a,b)) return a+b@decodef myfunc2(a,b,c): print('myfunc2(%s,%s,%s) called.' % (a,b,c)) return a+b+cmyfunc(1,2)myfunc2(1,2,3)总的来说,就是把修饰器第二层的固定参数,改为(*args,**kwargs),被修饰函数就可以接受不确定数量的参数了
第七步:带参数的修饰器,使修饰器更灵活,可控,参数可控制这个函数的作用,和特征
def deco(args):
def _deco(func): def __deco(): print('before %s called [%s].' % (func.__name__,args)) func() print('after %s called [%s]' % (func.__name__,args)) return __deco return _deco@deco('module1')def myfunc(): print('myfunc() called')@deco('module2')def myfunc2(): print('myfunc2() called')myfunc()myfunc2()
解析:如果修饰器带有参数,那么修饰器需要三层,第一层,args是修饰器的参数,第二层参数是传进被修饰函数,第三层没有参数
第八步:装饰器的参数是类
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()
解析:和第七步差不多一样装饰器,第一层参数是修饰器参数,第二层是函数,第三层没有参数.只是传进了类,可以相当于实例化一个类,可以用类里面的东西
第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
这步没多少难度,暂时跳过