作者:韩信子@ShowMeAI
教程地址:http://www.showmeai.tech/tuto...
本文地址:http://www.showmeai.tech/article-detail/89
申明:版权所有,转载请分割平台与作者并注明出处
Python命名空间和作用域
命名空间与作用域是程序设计中的根底概念,深刻了解有助于了解变量的生命周期,缩小代码中的莫名其妙bug。
1.命名空间
命名空间,也称为Namespace、名称空间或名字空间,指的是从名字到对象的一个映射关系,相似于字典中的键值对,Python中很多命名空间的实现用的就是字典。
命名空间提供了在我的项目中防止名字抵触的一种办法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是能够重名而没有任何影响。
以电脑文件目录为例,一个文件夹中能够蕴含多个文件夹,每个文件夹中不能有雷同的文件名,但不同文件夹中的文件能够重名。
个别有三种命名空间:
- 内置名称(built-in names), Python 语言内置的名称,比方函数名 abs、char 和异样名称 BaseException、Exception 等等。
- 全局名称(global names),模块中定义的名称,记录了模块的变量,包含函数、类、其它导入的模块、模块级的变量和常量。
- 部分名称(local names),函数中定义的名称,记录了函数的变量,包含函数的参数和部分定义的变量。(类中定义的也是)
- 命名空间查找程序:
假如咱们要应用变量showmeai,则 Python 的查找程序为:部分的命名空间去 -> 全局命名空间 -> 内置命名空间。
如果找不到变量showmeai,它将放弃查找并引发一个 NameError 异样:
NameError: name 'showmeai' is not defined。
- 命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行实现,则该命名空间的生命周期就完结。
因而,咱们无奈从内部命名空间拜访外部命名空间的对象。
num1 = 5def some_func(): # num2 是部分名称 num2 = 6 def some_inner_func(): # num3 是内嵌的部分名称 num3 = 7
如下图所示,雷同的对象名称能够存在于多个命名空间中。
2.作用域
作用域就是一个 Python 程序能够间接拜访命名空间的注释区域。
在一个 python 程序中,间接拜访一个变量,会从内到外顺次拜访所有的作用域直到找到,否则会报未定义的谬误。
Python 中,程序的变量并不是在哪个地位都能够拜访的,拜访权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序能够拜访哪个特定的变量名称。Python 的作用域一共有4种,别离是:
- L(Local):最内层,蕴含局部变量,比方一个函数/办法外部。
- E(Enclosing):蕴含了非部分(non-local)也非全局(non-global)的变量。比方两个嵌套函数,一个函数(或类) A 外面又蕴含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
- G(Global):以后脚本的最外层,比方以后模块的全局变量。
- B(Built-in): 蕴含了内建的变量/关键字等,最初被搜寻。
规定程序: L –> E –> G –> B。
在部分找不到,便会去部分外的部分找(例如闭包),再找不到就会去全局找,再者去内置中找。
g_count = 0 # 全局作用域def outer(): o_count = 1 # 闭包函数外的函数中 def inner(): i_count = 2 # 部分作用域
内置作用域是通过一个名为 builtin 的规范模块来实现的,然而这个变量名本身并没有放入内置作用域内,所以必须导入这个文件才可能应用它。在Python3.x中,能够应用以下的代码来查看到底预约义了哪些变量:
>>> import builtins>>> dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,内部也能够拜访,如下代码:
>>> if True:... msg = 'I am a member of ShowMeAI'... >>> msg'I am a member of ShowMeAI'>>>
实例中 msg 变量定义在 if 语句块中,但内部还是能够拜访的。
如果将 msg 定义在函数中,则它就是局部变量,内部不能拜访:
>>> def test():... msg_inner = 'I am a member of ShowMeAI'... >>> msg_innerTraceback (most recent call last): File "<stdin>", line 1, in <module>NameError: name 'msg_inner' is not defined>>>
从报错的信息上看,阐明了 msg_inner 未定义,无奈应用,因为它是局部变量,只有在函数内能够应用。
(1)全局变量和局部变量
定义在函数外部的变量领有一个部分作用域,定义在函数外的领有全局作用域。
局部变量只能在其被申明的函数外部拜访,而全局变量能够在整个程序范畴内拜访。调用函数时,所有在函数内申明的变量名称都将被退出到作用域中。如下示例代码:
total = 0 # 这是一个全局变量# 可写函数阐明def my_sum( arg1, arg2 ): #返回2个参数的和." total = arg1 + arg2 # total在这里是局部变量. print ("函数内是局部变量 : ", total) return total #调用sum函数my_sum( 10, 20 )print("函数外是全局变量 : ", total)
以上实例输入后果:
函数内是局部变量 : 30函数外是全局变量 : 0
(2)global和nonlocal关键字
当外部作用域想批改内部作用域的变量时,就要用到 global 和 nonlocal 关键字了。
以下示例代码批改全局变量 num:
num = 1def my_func(): global num # 须要应用 global 关键字申明 print(num) num = 123 print(num)my_func()print(num)
以上实例输入后果:
1123123
如果要批改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则须要 nonlocal 关键字了,如下实例:
def outer_num(): num = 10 def inner(): nonlocal num # nonlocal关键字申明 num = 100 print(num) inner() print(num)outer_num()
以上示例输入后果:
100100
另外有一种非凡状况,假如上面这段代码被运行:
a = 10def test(): a = a + 1 print(a)test()
以上程序执行,报错信息如下:
Traceback (most recent call last): File "test.py", line 7, in <module> test() File "test.py", line 5, in test a = a + 1UnboundLocalError: local variable 'a' referenced before assignment
错误信息为部分作用域援用谬误,因为 test 函数中的 a 应用的是部分,未定义,无奈批改。
批改 a 为全局变量:
a = 10def test_global(): global a a = a + 1 print(a)test_global()
执行输入后果为:
11
也能够通过函数参数传递:
a = 10def test_arg(a): a = a + 1 print(a)test_arg(a)
执行输入后果为:
11
3.视频教程
请点击到B站查看【双语字幕】版本
https://www.bilibili.com/vide...
材料与代码下载
本教程系列的代码能够在ShowMeAI对应的github中下载,可本地python环境运行,能迷信上网的宝宝也能够间接借助google colab一键运行与交互操作学习哦!
本教程系列波及的Python速查表能够在以下地址下载获取:
- Python速查表
拓展参考资料
- Python教程—Python3文档
- Python教程-廖雪峰的官方网站
ShowMeAI相干文章举荐
- python介绍
- python装置与环境配置
- python根底语法
- python根底数据类型
- python运算符
- python条件管制与if语句
- python循环语句
- python while循环
- python for循环
- python break语句
- python continue语句
- python pass语句
- python字符串及操作
- python列表
- python元组
- python字典
- python汇合
- python函数
- python迭代器与生成器
- python数据结构
- python模块
- python文件读写
- python文件与目录操作
- python谬误与异样解决
- python面向对象编程
- python命名空间与作用域
- python工夫和日期
ShowMeAI系列教程举荐
- 图解Python编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解AI数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程