两个函数的嵌套,内部函数使用到了外部函数的数据(变量),这个现象就可以称之为 产生闭包
由闭包衍生而来:函数间的嵌套,内部的函数用到了外部函数的数据(变量,或者说 东西)
作用:装饰器就是可以在不修改原函数内部代码的情况下,对其增加功能(增加代码)
函数内部去添加代码,增加功能,尽量不要去修改原函数内部的代码,用装饰器就可以避免这个缺点
def a(c): # 外部函数 def b(): # 内部函数 print('中华人民共和国的:', end='') c() # c 函数调用 return b @a # 要对其增加功能的函数,我们就称之为要被装饰的函数,对其增加功能的操作就称之为装饰 def demo1(): print('湖南省') @a def demo2(): print('湖北省') @a def demo3(): print('台湾省') demo1() demo2() demo3()一样的效果(理解篇):
def a(c): # 外部函数 def b(): # 内部函数 print('中华人民共和国的:', end='') c() # c 函数调用 return b # 要对其增加功能的函数,我们就称之为要被装饰的函数,对其增加功能的操作就称之为装饰 # @a # demo1 = a(demo1) def demo1(): print('湖南省') # @a # demo2 = a(demo2) def demo2(): print('湖北省') # @a # demo3 = a(demo3) def demo3(): print('台湾省') demo1 = a(demo1) demo1() demo2 = a(demo2) demo2() demo3 = a(demo3) demo3() 1、demo1 = a(demo1) demo1 >>> print('湖南省') 是实参 demo1 = c c() >>> print('湖南省') 2、a函数的调用, a(demo1)代表它的返回值本身b,>>> demo1 = b 指向了同一片内存空间,共用一份代码 3、demo1() 相当于 b() print('中华人民共和国的:', end=' ') c() >> print('湖南省') 最后的结果就是:中华人民共和国的:湖南省函数的三种情况:
无参数 无返回值
有参数 无返回值
有参数 又有返回值
一个函数被多个装饰器装饰
装饰器带有参数的情况
def a(c): def b(name): print('中华人民共和国的:',end='') c(name) return b @a def demo1(name): print('湖南省的%s' % name) demo1('长沙市') # 不管你传过来多少的参数,都能接住,可变参数、字典参数 def a(c): def b(*args,**kwargs): # 2步 name = '长沙市' print('中华人民共和国的:',end='') c(*args,**kwargs) # 原demo1 3步 '长沙市' 函数的调用 实参 return b @a def demo1(name): # 第4步 形参接住 print('湖南省的%s' % name) demo1('长沙市') # 第1步一个装饰器就是一个闭包,多个装饰器就是多个闭包
def a1(c): print('这是第一个装饰器。。。') def b1(*args,**kwargs): print('添加了第一种功能.。。') return c(*args,**kwargs) # 要被装饰的函数 >>> print('真帅气~') return b1 def a2(c): print('这是第二个装饰器***') def b2(*args,**kwargs): print('添加了第二种功能***') return c(*args,**kwargs) # 要被装饰的函数 return b2 @a2 # 2、demo = a2(demo) >>> demo = b2 # 3、当下面紧挨着变成了一个函数,马上就开始进行装饰 b2 = a1(b2) >> b2 = b1 @a1 # 1、不会发生改变 def demo(): print('真帅气~') demo()多个装饰器的分析:
demo = a2(a1(demo)),这样理解也是没有任何问题的关于传递参数:
def d(name): def a(c): def b(*args,**kwargs): print(name) print('我增加了一个功能') return c(*args,**kwargs) # 要被装饰的函数 return b return a @d('真厉害!') def demo(): print('我是要被装饰的函数***') demo()