概述
命名空间是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。
命名空间是提供了在项目中避免名字冲突的一种方法,各个命名空间是独立的,没有任何关系,
所以在一个命名空间中不能出现重名,但是不同的命名空间中可以重名却没有影响。
例如:
一、命名空间分类:
1.内置名称 built-in names
比如python语言内置的名称abs(),char()和异常名称BaseException、Exception等等
内置名称在python解释器启动时被创建,解释器退出时被删除
2.全局名称 global names
在模块中定义的名称,记录了模块的变量,如函数、类、其它导入的模块、模块级的变量和常量都是全局名称在模块被导入使用时创建,在解释器退出时退出
3.局部名称 local names
函数中定义的名称,记录了函数的变量,如函数的参数、函数内定义的变量、类的参数、类中定义的变量都是局部名称在函数调用的时候创建,在函数返回时被删除。
注意:
命名空间的生命周期主要取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束,因此无法从外部命名空间访问内部命名空间的对象。
二、命名空间的使用
2.1命名空间的查找:
Python 的查找顺序为:局部的命名空间去 -->全局命名空间 -->内置命名空间
2.2命名空间的创建:
python解释器启动 -->创建内置命名空间 --> 加载模块 --> 创建全局命名空间 -->函数被调用 -->创建局部命名空间
2.3命名空间的销毁:
函数调用结束 --> 销毁函数对应的局部命名空间 --> python解释器退出 -->销毁全局命名空间 -->销毁内置命名空间
总结:
一个模块的引入,函数的调用,类的定义都会引入命名空间,函数中的再定义函数,类中的成员函数定义会在局部命名空间中再次引入局部命名空间。
三、作用域
作用域就是一个 Python程序可以直接访问命名空间的正文区域。
直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
1.作用域的分类:
Local:最内层,包含局部变量,比如一个函数/方法内部
Enclosing:包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类)A里面又包含了一个函数 B,那么对于 B中的名称来说 A中的作用域就为 nonlocal
Global:当前脚本的最外层,比如当前模块的全局变量
Built-in:包含了内建的变量/关键字等,最后被搜索
作用域的规则顺序:Local-->Enclosing-->Global-->Built-in
如果变量在局部内找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再找不到就去内置中找
2.作用域的使用:
局部作用域、全局作用域和Enclosing作用域:
c = 0 #全局作用域
def fun():#Enclosing作用域
a = 1#闭包函数外的函数中,相对于函数 inner()来说 作用域非局部
print(a,'既不是全局变量也不是局部变量,是非局部变量')
def inter():#最里层函数
b = 2 # 局部作用域
print(b,'是局部变量')
inter()
print(c,'是全局变量')
Built-in:内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它
要查看预定义的变量可是先导入模块,使用dir()方法来查看
import builtins
dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,
其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,
也就是说这些语句内定义的变量,外部也可以访问
name = 'jack'
if chr('jack'.__eq__(name)):
result = 'I am from China'
else:
result = 'I am from USA'
print(result)
3、全局变量和局部变量
全局变量global:定义在函数外部拥有全局作用域的变量
全局变量在整个程序范围内都可以访问
局部变量local:定义在函数内部拥有局部作用域的变量
局部变量只能在其声明的函数内部使用,如果外部要使用只能通过函数的返回获得
t = 0 # 这是一个全局变量
# 函数说明
def fun(a1, a2):
# 计算两个数的和并返回"
t = a1 + a2 # t在这里是局部变量.
print("函数内是局部变量 : ", t)
return t
# 调用fun函数,传入参数的计算结果显示局部变量
fun(10, 20)
print("函数外是全局变量 : ", t)
#如果函数内部想要修改全局变量的值,则在函数内部要使用global声明其为全局变量
t = 0 # 这是一个全局变量
# 函数说明
def fun(a1, a2):
global t#声明接下来的t是访问全局变量t
# 计算两个数的和并返回"
t = a1 + a2 # t在这里是全局变量.
return t
# 调用fun函数,传入参数的计算结果显示局部变量
fun(10, 20)
print("函数外是全局变量 : ", t)
#如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
4.global和nonlocal的区别:
功能不同:
global关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量
nonlocal关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal 位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)
使用范围不同:
global关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global 修饰后也可以直接使用
nonlocal键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误
最后
以上就是忧心八宝粥为你收集整理的python基础语法11-命名空间/作用域的全部内容,希望文章能够帮你解决python基础语法11-命名空间/作用域所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复