网站首页 文章专栏 命名空间与作用域
文件1内容如下:
文件2内容如下:
如果我们运行文件2,结果会是什么呢?
可以看到,文件2中的from file_one import file_one_var1
语句执行后,文件1中的内容立即全部执行,所以输出了file one is running
。接着在文件2中输出了file_one_var1
的值,但是输出file_one_var2
时报错。
问题在于,明明文件1中的所有语句都执行过了,为什么file_one_var2
无法在文件2中使用?这涉及到python的命名空间与作用域问题。
*命名空间(Namespace)*:名字(标识符)到对象的映射。
简而言之,命名空间可以理解为:记录对象和对象名字对应关系的空间;现今 python 的大部分命名空间是通过字典来实现的,
也即一个命名空间就是名字到对象的映射,标识符是键,对象则是值。
*作用域(Scope)*:本质是一块文本区域,
Python 通过该文本区域可以直接访问相应的命名空间。
直接访问是指通过名字访问,如print(a)对a是直接访问;属性访 问指的是通过点号访问,如print(a.A)对A是属性访问。
特殊关键字
global
可以允许修改全局变量
nonlocal
将变量的命名空间由enclosing引入local
待增补。
这里c
是模块里的全局变量,在bar
函数中试图对全局变量进行修改,但是执行完bar
函数后打印c
,发现还是global
,修改失败。可以看到,这里在global域和local域各有一个对象c
,对全局变量的修改不可行。
这里使用global
关键字声明了全局变量,修改成功。注意global
关键字并没有把c
引入local域,因为打印locals()
函数发现local域没有对象。
定义了嵌套函数foo_in()
, 对foo_in()
来说,foo()
的作用域为enclosing。这里试图直接在local域使用enclosing域的对象,但是报错。
使用关键词nonlocal后,可以在local域使用enclosing域的对象,并且nonlocal可以把enclosing域的对象引入local域,因为打印locals()
后发现命名空间里有a
。