名称空间 作用域 闭包
什么是名称空间
名称空间是存放名字的地方,对于x=1来说,1存放在内存中,x这个名字和x=1之间的绑定关系存放在名称空间中。
名称空间的加载顺序
对于test.py来说
1、Python解释器先启动,先加载内置名称空间
2、对于test.py这个文件,加载文件中的全局名称空间,如函数名,定义的变量名
3、在执行文件中的代码的时候,调用函数,临时产生局部名称空间
名字的查找顺序
局部名称空间--》全局名称空间--》内置名称空间
在全局无法查看局部的,在局部可以查看全局的
作用域
作用域就是范围
- 全局作用域:内置名称空间、全局名称空间属于这个范围,全局存活,全局有效
- 局部作用域:局部名称空间属于该范围,临时存活,局部有效
作用域在函数定义的时候就确定了,与函数的调用位置无关
查看作用域:globals(),locals()
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> builtins
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间
闭包函数
内部函数包含对外部作用域而非全局作用域的引用
def counter():
n = 0
def incr():
nonlocal n
x = n
n+=1
return x
return incr
c = counter() # c 就是函数incr
print(c)
print(c()) # 0
print(c()) # 1
print(c()) # 2
print(c()) # 3
print(c.__closure__[0].cell_contents) # 擦看闭包的元素
闭包的意义与作用
返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,使得函数无论在何处被调用,都优先使用自己外层的作用域
应用:延迟计算
import requests
def index(url):
def get():
response = requests.get(url)
response.encoding = 'utf-8'
return response.text
return get
baidu = index('http://www.baidu.com')
print(baidu())
装饰器
装饰器是闭包函数的一种应用场景
一 为什么用装饰器
开放封闭原则:对修改封闭,对扩展开放
二 什么是装饰器
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
三 装饰器的使用
import time
def timer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print('run time is %s'%(stop_time-start_time))
return res
return wrapper
@timer
def foo():
time.sleep(3)
print('foo run')
foo()