名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值。各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响。
通俗讲:名称空间就是存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
原文链接:https://blog.csdn.net/lmseo5hy/article/details/80353099
存放着python的内置名称,如内置语言的名称如 len,char 和一些异常的名称 BaseException等,在任何模块都可以被调用,且随着python解释器的启动而产生,关闭而回收,因此它是第一个被加载的名称空间.
>>> len <built-in function len>
模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量,伴随着python文件的执行而产生
函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量,只有调用函数时才会产生,调用完成时便会被回收
>>> def func(): ... a = 1 ... >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name ‘a‘ is not defined >>>
内置命名空间(程序运行前加载)-->全局命名空间(程序运行中:从上到下加载)-->局部命名空间(程序运行中:调用时才加载)
局部的命名空间--> 全局命名空间 -> 内置命名空间。
当这三个命名空间还找不到时,会抛出NameError 异常
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
所以查找顺序为 : L –> E –> G –> B
#!/usr/bin/env python # -*- coding: utf-8 -*- total = 0 # 这是一个全局变量 def sum(x, y): # 返回2个参数的和." total = x + y # total在这里是局部变量. print("函数内是局部变量 : ", total) return total sum(1, 2) print("函数外是全局变量 : ", total) """ 函数内是局部变量 : 3 函数外是全局变量 : 0 """
当我们想在内部作用域修改外部作用域的变量时,可以使用 global 和 nonlocal 关键字.
#!/usr/bin/env python # -*- coding: utf-8 -*- total = 0 # 这是一个全局变量 def sum(x, y): # 返回2个参数的和." global total total = x + y # total在这里是局部变量. print("函数内是局部变量 : ", total) return total sum(1, 2) print("函数外是全局变量 : ", total) """ 函数内是局部变量 : 3 函数外是全局变量 : 3 """
def func1(): # 返回2个参数的和." a = 1 print("start a : ", a) def func2(): b = 2 def func3(): nonlocal a a = 3 func3() func2() print("end a : ", a) func1() """ start a : 1 end a : 3 """
a = 1 def test(): a = a + 1 print(a) test() """ UnboundLocalError: local variable ‘a‘ referenced before assignment """
这是因为在函数内部对变量赋值进行修改后,该变量就会被Python解释器认为是局部变量而非全局变量,当程序执行到a=a+1的时候,因为这条语句是给a赋值,所以a成为了局部变量,那么在执行return a(或是print a)的时候,因为a这个局部变量还没有定义,自然就会抛出这样的错误。
解决这个问题可以有以下几种方法:
1. 在函数内部声明global a
2.在函数内部重新定义一个a变量
3.通过函数传递参数
原文:https://www.cnblogs.com/liangweijiang/p/11829545.html