共计 3786 个字符,预计需要花费 10 分钟才能阅读完成。
作者:韩信子 @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 = 5
def 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_inner
Traceback (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 = 1
def my_func():
global num # 须要应用 global 关键字申明
print(num)
num = 123
print(num)
my_func()
print(num)
以上实例输入后果:
1
123
123
如果要批改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则须要 nonlocal 关键字了,如下实例:
def outer_num():
num = 10
def inner():
nonlocal num # nonlocal 关键字申明
num = 100
print(num)
inner()
print(num)
outer_num()
以上示例输入后果:
100
100
另外有一种非凡状况,假如上面这段代码被运行:
a = 10
def 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 + 1
UnboundLocalError: local variable 'a' referenced before assignment
错误信息为部分作用域援用谬误,因为 test 函数中的 a 应用的是部分,未定义,无奈批改。
批改 a 为全局变量:
a = 10
def test_global():
global a
a = a + 1
print(a)
test_global()
执行输入后果为:
11
也能够通过函数参数传递:
a = 10
def 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 数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程