1.7.1 命名空间
命名空间(NameSpace)是一个从名称到对象的映射。大部分命名空间由 字典 实现,内置命名空间由 builtins 模块实现。命名空间之间是独立的,避免了命名冲突。
1.7.2 命名空间的分类
1)内置命名空间
包含所有Python内置对象的名称,在 解释器启动时 创建,持续到解释器终止。被所有的Python文件所共享。
2)全局命名空间
一个.py 文件即是一个python模块,每个模块都有一个各自的全局命名空间。记录了模块的 全局变量、类、函数、导入的其它模块 等。在 模块被读入时 创建,持续到解释器退出。
3)局部命名空间
记录了函数的 变量的参数 。在 函数被调用时 创建,持续到函数调用结束。
命名空间的查找顺序默认优先级:局部命名空间 > 全局命名空间 > 内置命名空间
1.7.3 exel()函数和eval()函数【都可以执行字符串形式的 python 代码】
eval(expression [, globals [, locals ]]);只能接收一个表达式;返回表达式的结果;
exec(object [, globals [,locals ]]);可以接收多个表达式组成的代码块;无返回值,返回None;
注:globals 和 locals 参数为字典,指代 表达式的全局命名空间和局部命名空间,并且如果函数包含了globals和locals参数,表达式执行的时候只能从参数globals 和 locals 的命名空间中取值。
如果locals参数没有传递而只传递了globals参数,那么 locals 取和globals相同的值。
# 验证eval函数 a = 1 b = 2 def fun1(): a = 3 print(eval("a+b")) # 5 print(eval("a+b", {'a':4, 'b':5})) # 9 print(eval("a+b", {'a':4, 'b':5}, {'a':6, 'x':7})) # 11 print(eval("a+b", {'a':6, 'x':7}, {'a':8, 'y':9})) # 命名空间找不到变量b,报错。
1.7.4 作用域
python程序可以直接访问的命名空间的正文区域。
作用域分类:局部作用域(Local) > 闭包函数外的函数中(Enclosing) > 全局作用域(Global) > 内置作用域(Built-in) ;当前作用域内找不到变量值的时候会自动向下一个作用域寻值。
只有模块(module)、类(class)以及函数(def、lambda)才会引入新的作用域。案例如下:
# if 、while等分支不会引入新的作用域 a = 123 if a == 123: a = 456 print(a) # 456 print(a) # 456
1.7.5 人为指定变量的作用域
1 # 下面代码会报错,分析:表达式 a+1 在执行的时候会发生:变量a在执行之前引用。 2 3 def fun2(): 4 a = a + 1 5 print(a) 6 7 a = 123 8 fun2() # 9 print(a)
分析: 8th 调用fun2函数,会报错:在fun2函数中,将表达式 a+1 赋值给 a,语法检查器检查到 局部命名空间中有定义变量a,所以 在执行表达式的时候,不会去访问全局变量a,而在局部作用域中,变 量a的赋值又是在表达式执行之后,所以会报 “变量a在赋值之前引用” 错误。
解决:
# 解决 def fun2(): global a # 通过global关键字指定局部作用内的a全部使用 全局变量 a = a + 1 print(a) a = 123 fun2() print(a)
global关键字和 nonlocal关键字:
如上示例:global强制使用全部变量;nonlocal强制使用闭包函数外函数内变量!!!
结尾小甜点:
def outer(): lst = [1,2] def inner(): res = lst.append(3) lst = lst.append(3) print(lst, res) # None, None outer()
为啥会输出两个None?因为append函数没有返回值!
标签:1.7,函数,作用域,空间,print,命名,locals From: https://www.cnblogs.com/zhangzhenw/p/17963886