Skip to content

变量作用域

变量作用域

简介

作用域就是一个 Python 程序可以直接访问命名空间的正文区域。

在一个 Python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。

Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有 4 种,分别是:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量,一般在闭包中出现。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

查找规则顺序: L –> E –> G –> B

在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

根据作用域的不同,变量可分为局部变量和全局全量。

局部变量

局部变量是指在函数内部定义并使用的变量,它只在函数内部有效,即函数内部的名字只在函数运行时才会创建,在函数运行之前或者运行完毕之后,所有的名字就都不存在了。

所以,如果在函数外部使用函数内部定义的变量,就会抛出 NameError 异常。

示例

def show():
    # 局部变量
    a = 10
    print(a)

# 在函数外无法访问局部变量a
# print(a)
# 只能通过调用函数使用局部变量
show()
# 函数外无法访问局部变量a
# print(a)

定义在函数内部的局部变量,只在函数内部可以被访问。局部变量在函数被调用时被创建,在函数执行结束后被销毁。

全局变量

定义在函数外之外的变量为全局变量,全局变量可以在当前程序文件的任何位置进行访问 。

示例

# 全局变量定义
m = 20
def show1():
    # 使用全局变量
    print("show1:", m)

def show2():
    # 使用全局变量
    print("show2:", m)

# 使用全局变量
print(m)
show1()
show2()
# 使用全局变量
print(m)

当全局变量和局部变量同名时,根据作用域的查找规则顺序,内部变量会屏蔽全局变量。

示例

# 全局变量定义
m = 10
def show():
    # 局部变量与全局变量同名
    m = "ABC"
    # 使用局部变量
    print("show:", m)

# 使用全局变量
print(m)
show()
# 使用全局变量
print(m)

从上面的代码中可以看出,如果想在函数内部修改全局变量时,会被解释成同名变量屏蔽,此时,需要使用 global 关键字

示例

# 全局变量定义
m = 10
def show():
    # 声明此变量是函数外定义的全局变量
    global m
    # 修改全局变量的值
    m = "ABC"
    # 使用全局变量
    print("show:", m)

# 使用全局变量
print(m)
show()
# 使用全局变量
print(m)

全局变量和局部变量的优缺点

全局变量的优点:

  1. 全局变量在整个程序中都可访问,方便在不同的函数或模块之间共享数据。
  2. 全局变量可以保存程序运行期间的状态,比如计数器或状态标志。

全局变量的缺点:

  1. 全局变量的作用范围很大,容易被误修改,导致程序出现错误。
  2. 在多个函数中使用同名的全局变量时,很容易出现混淆和命名冲突的问题。
  3. 全局变量的使用不宜过多,因为它们会占用内存资源。如果程序中有太多的全局变量,会增加维护和调试的难度。

局部变量的优点:

  1. 局部变量的作用范围限于所在的函数或代码块中,不会对其他函数或模块造成影响。这样可以防止变量的误修改或命名冲突。
  2. 局部变量仅在需要时才会被创建和销毁,节省了内存资源。

局部变量的缺点:

  1. 局部变量的作用范围有限,不能在其定义范围外直接访问。如果需要在多个函数之间共享数据,就不能使用局部变量,需要采用其他的方式来传递数据。
  2. 当函数中定义了较多的局部变量时,可能会使代码显得冗长和难以阅读,增加了编写和维护的复杂性。

在编写程序时,应根据具体的需求来选择使用全局变量还是局部变量。

如果需要在多个函数中共享数据,可以选择使用全局变量;如果只在某个函数内部使用的变量,可以选择使用局部变量。

同时,需要注意合理命名变量,以避免命名冲突和混淆。