一、名称空间
1、命名空间一共分为三种:
全局命名空间:是在程序从上到下被执行的过程中依次加载进内存里面,放置了我们设置的所有变量名和函数名;在全局命名空间中,可以使用内置命名空间中的名字,但是不能用局部中使用。
局部命名空间:就是函数定义的名字,当调用函数的时候才会产生这个名称空间,随着函数的执行结束而消失;在局部命名空间中,可以使用全局、内置命名空间中的名字。
内置命名空间:在python解释器一启动就可以使用的名字,这个是存储在内置命名空间中的,内置名字在启动解释器的时候被加载到内存中;在内置命名空间中,不能使用全局和局部的名字。
2、命名空间之间的加载与取值顺序:
加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)
在正常情况下,直接使用内置的名字,当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字
取值:
在局部调用:局部命名空间->全局命名空间->内置命名空间
在全局调用:全局命名空间->内置命名空间
3、命名空间的查找顺序
命名空间的查找顺序
a) 如果在函数内调用一个变量,先在局部命名空间查找,如果找到则停止查找。否则在全局命名空间查找,如果还是没找到,则查找内置命名空间。如果以上三个命名都未找到,则会报错。
b) 如果在函数外调用一个变量,则在全局命名空间,局部命名空间此时不可见,如果找到则停止查找,否则到内置命名空间中查找。如果两者都找不到,则报错。只有当局部命名空间内,使用global 关键字声明了一个变量时,查找顺序则是 a的查找顺序。实例如下:
#!/usr/bin/python
# -*- encodeing:utf-8 -*-
name = 'caoyf'
def func():
#global name
name = 'Fangsw'
print(name)
func()
print(name)
二、作用域
1、作用域说明:作用域是小范围作用域可以使用大范围的变量,但是反之不行,他是单向的。
全局作用域 —— 作用在全局 —— 内置和全局名字空间中的名字都属于全局作用域 ——globals()
globals 永远打印全局的名字
对于不可变数据类型 在局部可以是查看全局作用域中的变量
但是不能直接修改
如果想要修改,需要在程序的一开始添加global声明
如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效
a = 1
def func():
global a
a = 2
func()
print(a)
#此时结果显示:2 因为函数内声明了变量a=2 若将global a #注释掉,则print(a)=1
2、局部作用域 —— 作用在局部 —— 函数(局部名字空间中的名字属于局部作用域) ——locals()
locals 输出什么 根据locals所在的位置
locals 返回一个名字/值对的字典。这个字典的键字是字符串形式的变量名字,字典的值是变量的实际值。
#!/usr/bin/python
# -*- encodeing:utf-8 -*-
# a = 1
# b = 2
# def func():
# x = 'aaa'
# y = 'bbb'
# print(locals())
# print(globals())
#
# func()
# 此时locals是在局部作用域内,所以显示是{'y': 'bbb', 'x': 'aaa'}
# a = 1
# b = 2
# def func():
# x = 'aaa'
# y = 'bbb'
# print(locals())
# print(globals())
#
# func()
# 此时locals是在全局作用域内,所以显示的是全局的名字
3、函数的嵌套:
函数嵌套的定义:内部函数可以使用外部函数的变量。
#!/usr/bin/python
# -*- encodeing:utf-8 -*-
a = 1
def outer():
a = 1
def inner():
a = 2
def inner2():
# nonlocal a #声明了一个上面第一层局部变量 a=2
a = 1 #不可变数据类型的修改
print('+',a)
inner2()
print('##a## : ', a)
inner()
print('**a** : ',a)
outer()
print('全局 :',a)打印显示: + 1
##a## : 2
**a** : 1
全局 : 1
nonlocal只能用于局部变量,找上层离当前函数最近的局部变量。
声明了nonlocal的内部函数的变量修改会影响到,离当前函数最近一层的局部变量。
对全局无效,对局部也只是对最近一层有影响。