浅析Python中全局变量和局部变量的使用

 更新时间:2021年06月11日 20:59:28   作者:写bug写bug  
一个变量的名称除了可以代表不同的东西以外,也表示“哪里可以使用”这个变量,这篇文章将会介绍全局变量和局部变量的用法和差异,感兴趣的可以了解下

什么是全局变量和局部变量?

在Python中,主程序和每个函数都拥有自己的命名空间(namespace)。简单的区分规则如下:

  • 主程序定义了“全局”的命名空间,主程序中定义的变量是“全局变量”。
  • 每个函数定义了“局部”的命名空间,函数内部定义的变量就是“局部变量”。
  • 每个命名空间中的变量名称都是“唯一的”。不同命名空间内的变量名称可以相同,例如函数A可以定义一个变量a,函数B也可以定义一个变量a,这两个a变量是完全不同的变量。

比如有个人叫小明,在同一个家庭里只会有一个小明,而不同的家庭可以有不同的小明(不同的人,但都叫小明),但如果这群小明去到学校,就必须额外命名以区分哪个小明是小明(一个学校只会有一个小明,其他的可能是小明一号、小明二号等)。

默认的命名空间

Python默认提供三个命名空间,分别是内置的Built-in(Python预设的函数名如abs、char等)、全局Global和局部Local三种。当使用变量时,会从最内层(局部命名空间)开始向外层搜索,直到找到对应的名称为止(如果找不到就会抛出错误)。

弄清楚到底使用了哪个变量

下面这段代码定义了两个变量a,因为两个变量a处于不同的命名空间,所以打印出来的结果是不同的。

注意,函数名也属于变量名称,如果将函数定义为a,就会覆盖全局变量a的内容。

a = 1  # 定义全局变量a等于1
def hello():  # 定义hello函数
    a = 2  # 定义局部变量a等于2
    print(a)
    
hello()  # 2
print(a)  # 1

如果在hello函数里没有定义变量a,而是“单纯使用变量a”,这时程序会先查找hello函数的命名空间里是否有变量a,如果找不到,就会向外层寻找,找到之后就会使用该变量的内容。以下例子,执行hello函数后就会打印出10。

a = 1
def hello():
  print(a+9)    # 使用全局变量的 a

hello()         # 10
print(a)        # 1

如果将全局变量a移除,执行过程最后就会发生错误,因为最后一个print(a)是寻找全局变量a,因为找不到所以就会出错。

def hello():
  a = 1
  print(a)

hello()
print(a)    # 发生错误,因为找不到变量 a

同理,如果是不同函数,如果要互相调用对方的变量,也会发生错误。

def hello():
  a = 1
  print(a)

def test():
  print(a)

hello()
test()    # 发生错误,因为找不到变量 a

使用global修改全局变量

如果要在函数里修改全局变量,可以使用「global 全局变量」的方式。

a = 1         # 定义全局变量 a 等于 1
def hello():  # 定义 hello 函数
  global a    # 声明下方的 a 为全局变量 a
  a = 2       # 修改 a 为 2

print(a)      # 1
hello()       # 执行 hello 函数
print(a)      # 2 ( 全局变量 a 被修改为 2 )

全局变量和局部变量容易遇到的陷阱

如果变量的内容是列表、字典或集合,在处理“全局变量和局部变量”时,与处理“多个变量同时赋值”时一样,很容易会遇到赋值的陷阱,因为变量只是“标签”,当多个变量同时指向一个列表、字典或集合时,只要变量内容被修改(并非使用等号赋值),不论这个变量是全局还是局部变量,另一个变量内容也会跟着变动。

下面的例子执行后,f1函数的a不受作用域的影响,使用append发生“改变”后,不论a在何处都会被影响,连带b也被影响,但c因为是通过等号“声明赋值”,就会变成“局部变量”,因此在f1函数作用域之外的c就不会被影响,d也不会被影响。不过如果在f1的开头加上global c,等同于将c从局部变量提升到全局变量,f2里的c就会被影响。

a = []
b = a
c = []
d = c

def f1():
    # global c        # 如果加上这行,f2 里的 c 就会被影响
    a.append(1)
    c = [1]
    print(a)  # [1]
    print(b)  # [1]   # 被影响
    print(c)  # [1]
    print(d)  # []    # 不受影响

def f2():
    print(a)  # [1]   # 被影响
    print(b)  # [1]   # 被影响
    print(c)  # []    # 不受影响,但如果 f1 加上 global c,此处就会被影响
    print(d)  # []    # 不受影响

f1()
f2()

global() 和 local()

global() 和 local() 是两个可以打印出当前变量的方法:

  • global():返回一个字典,内容是“全局命名空间”的内容。
  • local():返回一个字典,内容是“局部命名空间”的内容。

下方的程序,执行 hello 函数后会打印出局部命名空间和全局命名空间的内容。

a = 1
def hello():
  a = 1
  print(locals())
  print(globals())

hello()
print(a)

如果将locals()放到全局命名空间里,则打印出来的结果和global()相同。

a = 1
def hello():
  a = 1
hello()
print(locals())
print(globals())

到此这篇关于浅析Python中全局变量和局部变量的使用的文章就介绍到这了,更多相关Python全局变量和局部变量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python numpy和matlab的几点差异介绍

    Python numpy和matlab的几点差异介绍

    这篇文章主要介绍了Python numpy和matlab的几点差异,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • python3使用Flask实现api数据接口的示例详解

    python3使用Flask实现api数据接口的示例详解

    这篇文章主要为大家详细介绍了python3如何使用Flask实现api数据接口,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-09-09
  • Django admin 实现search_fields精确查询实例

    Django admin 实现search_fields精确查询实例

    这篇文章主要介绍了Django admin 实现search_fields精确查询实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • python 线程池顺序执行的方法实现

    python 线程池顺序执行的方法实现

    在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-08-08
  • python基础入门详解(文件输入/输出 内建类型 字典操作使用方法)

    python基础入门详解(文件输入/输出 内建类型 字典操作使用方法)

    这篇文章主要介绍了python基础入门,包括文件输入/输出、内建类型、字典操作等使用方法
    2013-12-12
  • JAVA及PYTHON质数计算代码对比解析

    JAVA及PYTHON质数计算代码对比解析

    这篇文章主要介绍了JAVA及PYTHON质数计算代码对比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Python调用命令行进度条的方法

    Python调用命令行进度条的方法

    这篇文章主要介绍了Python调用命令行进度条的方法,涉及Python进度条的调用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-05-05
  • Python中的POST请求参数详解

    Python中的POST请求参数详解

    这篇文章主要介绍了Python中的POST请求参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Python中整数的缓存机制讲解

    Python中整数的缓存机制讲解

    今天小编就为大家分享一篇关于Python中整数的缓存机制讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02
  • 安装pyhttpx解决ImportError: DLL load failed错误

    安装pyhttpx解决ImportError: DLL load failed错误

    这篇文章主要为大家介绍了安装pyhttpx解决ImportError: DLL load failed错误,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论