名称空间(namespaces)与作用域

引入

在python解释器中运行一行代码import this就可以看到"传说"中的python之禅,它体现了使用python进行开发的规范,而最后一句 - Namespaces are one honking great idea -- let's do more of those!就是本文的主角。

名称空间(Namespaces)

名称空间就是存放名字与对象绑定关系的地方,是对栈区的划分。定义一个变量。name = 'python',解释器会申请内存空间存放值'python',将名字name与'python'的内存地址的绑定关系存在栈区中。

有了名称空间之后就可以在栈区中存放相同的名字,在程序执行期间最多会存在三种名称空间,每种名称空间相互独立。

内置名称空间(built-in)

存放的是python解释器内置的名字,比如python中的保留字(关键字)。python解释器启动时内置名称空间就会产生,python解释器关闭,则销毁。

python 复制代码
# 在交互式的解释器环境中输入print然后回车
>>> print
<built-in function print>

全局名称空间

只要不是函数内定义也不是内置的名字,剩下的全部都是全局名称。全局名称空间在运行python文件时产生,python文件执行完成之后销毁。

python 复制代码
x = 1  # x是全局名称
def func():  # func是全局名称
    print(x)  # print是内置名称

局部名称空间

函数内定义的名字都会被存放在局部名称空间。局部名称空间在调用函数时产生,函数运行完毕后销毁。

python 复制代码
def func():  # func全局名称
    x = 100  # x局部名称
    print(x)  # print内置名称 

名称空间与作用域

名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间。

名称空间销毁顺序是:局部名称空间->全局名称空间->内置名称空间。

按照名称空间中名字的作用范围可以将三种名称空间划分为两个区域。

全局作用域---全局名称空间、内置名称空间中的名字属于全局作用域,全局作用域中的名字在整个文件执行过程中都不会被销毁,在任意位置都可以使用。

局部作用域---位于局部名称空间中的名字属于局部作用域,局部作用域中的名字在函数调用时产生,调用结束时销毁,只能在函数内使用。

作用域与名字查找优先级

名字顺序的查找需要记住一条准则:名字的查找顺序以函数阶段为准,与调用阶段没有关系。

  • 从局部作用域开始

在局部作用域查找名字,起始位置是局部作用域,现在局部名称空间中查找,找不到再去全局作用域查找,先查找全局名称空间,找不到再去内置名称空间,最后都找不到会抛出异常。

  • 从全局作用域开始

在全局作用域查找名字时,起始位置就是全局作用域,先查找全局名称空间,找不到再去内置名称空间,最后都找不到会抛出异常。

  • 名称空间的"嵌套关系"

这里的嵌套可以理解为不同的名称空间都存在同样的变量名,注意:一定要以函数定义阶段为准,并且牢记名称空间的查找顺序。

global & nonlocal

如果想要在函数内修改全局名称空间中名字的值并且该值是不可变数据类型,需要用到global关键字,如果该值是可变数据类型,则无需使用global,可以直接对原值进行修改。

python 复制代码
x = 100
l = [1, 2]
def func():
    global x  # 声明x是全局名称空间的名字
    x = 101
    l.append(3)
func()
print(x)  # 101
print(l)  # [1, 2, 3]

对于嵌套多层的函数,可以使用nonlocal关键字对外层嵌套函数定义的名字进行声明并修改其值。nonlocal会从当前函数的外层函数一层一层去查找声明的名字,如果在最外层函数的名称空间中找不到该名字,会抛出异常。

python 复制代码
def func():
    x = 10
    def func1():
        nonlocal x  
        x = 11
    func1()  # 修改func作用域中x的值
    print(x)  # 在func作用域中查看x的值
func()  # 11

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关推荐
程序员勋勋12 分钟前
【自动化测试】如何在jenkins中搭建allure
职场和发展·jenkins·测试覆盖率
咕咕吖36 分钟前
对称二叉树(力扣101)
算法·leetcode·职场和发展
sszmvb12342 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
测试杂货铺2 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
码农派大星。3 小时前
软件测试--BUG篇
功能测试·bug
测试界萧萧3 小时前
外包干了4年,技术退步太明显了。。。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
小码哥说测试3 小时前
接口测试用例设计的关键步骤与技巧解析!
自动化测试·测试工具·jmeter·职场和发展·测试用例·接口测试·postman
霍格沃兹测试开发学社测试人社区3 小时前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
linsa_pursuer4 小时前
快乐数算法
算法·leetcode·职场和发展
阑梦清川11 小时前
在鱼皮的模拟面试里面学习有感
学习·面试·职场和发展