针对软件开发的“开放-封闭”原则,即:python
封闭:已实现的功能代码块不该该被修改闭包
开放:对现有功能的扩展开放函数
所谓的装饰器,就是经过装饰器函数,来修改原函数的一些功能,使得原函数不须要修改。this
def f1(): print('f1 called: ') def f2(): print('f2 called: ')
def w1(func): def inner(): print('----权限验证----') func() return inner
review:闭包函数的条件code
① 在一个外函数中定义了一个内函数。开发
② 内函数里运用了外函数的临时变量。class
③ 而且外函数的返回值是内函数的引用。test
# 在执行w1函数的时候,此时直接把inner函数返回了,同时把它赋值给f1 # 此时的f1已经不是未加装饰时的f1了,而是指向了w1.inner函数地址 def w1(func): def inner(): print('----权限验证----') func() return inner # 当python解释器执行到这句话的时候,会去调用w1函数,同时将被装饰的函数名做为参数传入(此时为f1) @w1 # f1 = w1(f1) def f1(): print('f1 called: ') @w1 def f2(): print('f2 called: ') # 在调用f1()的时候,其实调用的是w1.inner函数 # 那么此时就会先执行权限验证,而后再调用原来的f1(),该处的f1就是经过装饰传进来的参数f1 f1() f2() ''' ----权限验证---- f1 called: ----权限验证---- f2 called: '''
这样下来,就完成了对f1的装饰,实现了权限验证。变量
若是原函数有参数,那闭包函数必须保持参数个数一致,而且将参数传递给原方法扩展
def w_say(fun): def inner(name): # 此处应有参数 """ 若是被装饰的函数有形参,那么闭包函数必须有参数 :param name: :return: """ print('say inner called') fun(name) # 将参数传给原方法 return inner @w_say def hello(name): print('hello ' + name) hello('Vivian') ''' say inner called hello Vivian '''
def w_add(func): def inner(*args): print('add inner called') func(*args) return inner @w_add # 共有装饰器,被装饰的函数的形参不固定 def add(a, b): # 被装饰的函数有形参 print('%d + %d = %d' % (a, b, a + b)) @w_add def add2(a, b, c): print('%d + %d + %d = %d' % (a, b, c, a + b + c)) add(2, 4) add2(2, 4, 6) ''' add inner called 2 + 4 = 6 add inner called 2 + 4 + 6 = 12 '''
def w_test(func): def inner(): print('w_test inner called start') # 对test进行调用以后,接收返回值s str0 = func() # 原test的返回值传递给str0 print('w_test inner called end') # 被装饰以后的test返回值为str0 return str0 return inner @w_test # test = w_test(test) def test(): print('this is test fun') return 'hello' ret = test() print('ret value is %s' % ret) ''' w_test inner called start this is test fun w_test inner called end ret value is hello '''