变量作用域
变量作用域
简介
作用域就是一个 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)
全局变量和局部变量的优缺点
全局变量的优点:
- 全局变量在整个程序中都可访问,方便在不同的函数或模块之间共享数据。
- 全局变量可以保存程序运行期间的状态,比如计数器或状态标志。
全局变量的缺点:
- 全局变量的作用范围很大,容易被误修改,导致程序出现错误。
- 在多个函数中使用同名的全局变量时,很容易出现混淆和命名冲突的问题。
- 全局变量的使用不宜过多,因为它们会占用内存资源。如果程序中有太多的全局变量,会增加维护和调试的难度。
局部变量的优点:
- 局部变量的作用范围限于所在的函数或代码块中,不会对其他函数或模块造成影响。这样可以防止变量的误修改或命名冲突。
- 局部变量仅在需要时才会被创建和销毁,节省了内存资源。
局部变量的缺点:
- 局部变量的作用范围有限,不能在其定义范围外直接访问。如果需要在多个函数之间共享数据,就不能使用局部变量,需要采用其他的方式来传递数据。
- 当函数中定义了较多的局部变量时,可能会使代码显得冗长和难以阅读,增加了编写和维护的复杂性。
在编写程序时,应根据具体的需求来选择使用全局变量还是局部变量。
如果需要在多个函数中共享数据,可以选择使用全局变量;如果只在某个函数内部使用的变量,可以选择使用局部变量。
同时,需要注意合理命名变量,以避免命名冲突和混淆。