今天晚上下象棋下得头疼,发一篇讲命名空间的旧笔记吧
一、基本概念
标识符
也就是变量名,比如 a = [1, 2, 3],a就是标识符
命名空间
是一个dict,其中key是标识符,value是repr(标识符)
三条规则
赋值(包括显示赋值和隐式赋值)产生标识符,赋值的地点决定标识符所处的命名空间
函数定义(包括def和lambda)产生新的命名空间
python搜索一个标识符的顺序是LEGB,如果都找不到,将放弃查找并抛出一个NameError异常
LEGB: 指python的四层命名空间,其中E层也可不计,只LGB层
L层: (local),在一个函数定义中,【并且这个函数里没有再包含其他函数】
E层: (enclosing function),表示在一个函数定义中,【但这个函数里还包含有其他函数】(闭包)
G层: (global),指一个module的命名空间,也就是说在一个.py文件中
B层: (builtin),内置模块的命名空间,指的是builtin.py模块里的,任何位置均可访问
二、访问
L层和E层可以用locals()函数访问,G层可以用globals()访问,B层默认所有地方都可以访问,而且任何一个命名空间里都会自动包括进B层,也就是
注意,在函数外部,
三、导入
当模块被导入的时候如果语法是from module import something,是把something导入到了自己的命名空间如果语法是import module,那么是把module导入到了当前自己的命名空间,而module还保持着自己的命名空间,如果要使用里面的函数需要module.something这样写。同时用globals()或者locals()只能访问到module,无法直接得到module.something
而命名空间也可以手动创建,如下代码,可见 已经被自动添加进了这个命名空间
四、其他
locals()是只读的,globals()不是,因为locals()返回的只是真正命名空间的一个拷贝,而非命名空间本身,所以无法修改,而globals()返回的是实际命名空间。具体原因可以看这里: https://segmentfault.com/a/1190000012724861
而我们说locals()只读不是说他不能改,而是说他改了没用,如下面代码,修改locals时没有问题,修改之后locals也能输出,但是真正使用的时候是无法生效的
来源:方禾黎
领取专属 10元无门槛券
私享最新 技术干货