函数的闭包和装饰器
函数的闭包:
#1.闭 必须是内部的函数
#2.包 引用了外部作用域中的变量
命名空间:
一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间
作用域(包括函数的作用域链):
小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)
在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错
函数的嵌套:
嵌套调用
嵌套定义:定义在内部的函数无法直接在全局被调用
函数名的本质:
就是一个变量,保存了函数所在的内存地址
闭包:
内部函数包含对外部作用域而非全局作用域名字的引用,该内部函数称为闭包函数
在闭包的基础上延伸出来一个小东西————装饰器
装饰器的本质:一个闭包函数
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
开放封闭原则
1.对扩展是开放的
为什么要对扩展开放呢?
我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
2.对修改是封闭的
为什么要对修改封闭呢?
就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
装饰器完美的遵循了这个开放封闭原则。
装饰器的主要功能和装饰器的固定结构
装饰器的主要功能:
在不改变函数调用方式的基础上在函数的前、后添加功能。
装饰器的固定格式:
1 def timer(func): 2 def inner(*args,**kwargs): 3 '''执行函数之前要做的''' 4 re = func(*args,**kwargs) 5 '''执行函数之后要做的''' 6 return re 7 return inner
语法糖————@装饰器名
带参数的装饰器
1 def deco(arg): 2 def _deco(func): 3 def __deco(): 4 print("before %s called [%s]." % (func.__name__, arg)) 5 func() 6 print(" after %s called [%s]." % (func.__name__, arg)) 7 return __deco 8 return _deco 9 10 @deco("mymodule") 11 def myfunc(): 12 print(" myfunc() called.") 13 14 @deco("module2") 15 def myfunc2(): 16 print(" myfunc2() called.") 17 18 myfunc() 19 myfunc2()