【37.函数-命名空间】
命名空间又称为name space,顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量 x = 1,存放于内存中,那名字x存放在哪里呢?
名称空间正式存放名字x和1绑定关系的地方
名称空间共3种
1.locals:是函数内的名称空间,包括局部变量和形参
2.globals:全局变量,函数定义所在模块的名字空间
3.builtins:内置模块的名字空间
不同变量的作用域不同就是由这个变量的所在的命名空间决定的
作用域即范围
全局范围:全局灵活,全局有效
局部范围:临时存活,局部有效
查看作用域的方法globals(),locals()
【38.函数-作用域的查找空间】
作用域的查找顺序
LEGB>>locals->enclosing function ->globals->__builtins__
1.locals:是函数内的名称空间,包括局部变量和形参
2.enclosing 外部嵌套函数的命名空间
3.globals:全局变量,函数定义所在模块的名字空间(打印所在脚本的所有变量)
4.builtins:内置模块的名字空间
【39.函数-闭包】
闭包只是个概念性的东西,在外部可以执行内部函数,而且可以在外部调用内部函数的值
在外层函数执行的时候,内层函数被返回,可以调用内层函数的变量
def func(): n = 10 def func2(): print("fun2",n) return func2 f = func() print(f) f()
输出结果
闭包:关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量
参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。
而当这个内部函数执行时,它仍然必须访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值
但是也会受外部函数的影响
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,在函数无论在何处调用,优先使用自己外层的
-------------------------------------------------------------------------------
【40.函数-装饰器】
重要知识点!
软件开发的原则:开放-封闭原则,已经实现功能的代码是不能被修改的,但是可以被扩展
所以如何在不改变原有功能代码的情况下,加上新的功能呢?
高阶函数的特性,把一个函数当做一个参数,或者当做返回值给另一个函数(函数的嵌套就可以实现)但是这样会修改调用的方式,这样是不可以的
【41.函数-装饰器流程分析】
装饰器:在符合开放-封闭的原则下,为代码加上新的功能(闭包+函数的重新赋值)
语法糖:装饰器@,只能加到函数的上方
【42.函数-装饰带参数的函数】
为装饰器加上非固定参数(*args,**kwargs)
【43.函数-装饰器带参数2】
--------------------------------------------------------------------------------
装饰器部分重新学
def timer(func): def inner(*args,**kwargs): '''执行函数之前要做的''' re = func(*args,**kwargs) '''执行函数之后要做的''' return re return inner @timer def aaa():print(‘a’)
装饰器再读
# def wrapper(f): #装饰器函数,f是被装饰的函数
# def inner(*args,**kwargs):
# '''在被装饰函数之前要做的事'''
# ret = f(*args,**kwargs) #被装饰的函数
# '''在被装饰函数之后要做的事'''
# return ret
# return inner
#
# @wrapper #语法糖 @装饰器函数名
# def func(a,b): #被装饰的函数
# time.sleep(0.01)
# print('XXXX',a,b)
# return 'XXX'