关于python:图解python-命名空间与作用域

0次阅读

共计 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 数学根底:从入门到精通系列教程
  • 图解大数据技术:从入门到精通系列教程

正文完
 0