作者:韩信子@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数学根底:从入门到精通系列教程
  • 图解大数据技术:从入门到精通系列教程