变量的作用域
1.局部作用域(Local)
每次调用函数时都会创建一个局部作用域。
局部作用域(函数)中定义的变量称之为局部变量。
局部变量的作用域为:从定义变量处开始到函数结束。
函数调用结束后,其对应的局部作用域中的所有变量都会被销毁。
2.嵌套作用域(Enclosing)
每次调用嵌套函数中的外函数时都会创建一个嵌套作用域。
当在外函数内定义变量时,该变量的作用域为:从定义变量处开始到函数结束
外函数调用结束后,其对应的嵌套作用域中的所有变量都会被销毁。(闭包除外)
3.全局作用域(Global)
每次运行模块时都会创建一个全局作用域。
全局作用域(模块)中定义的变量称之为全局变量
全局变量的作用域:从定义变量处开始到模块结束
程序运行结束后,全局作用域中的所有变量都会被销毁。
4.内置作用域(Built-in)
每次启动Python解释器都会自动加载内置模块,从而创建一个内置作用域。
内置模块中的函数(内置函数),可以在程序中直接使用。
停止解释器后,内置作用域中的所有变量都会被销毁。
print(id(123)) # id是内置作用域
id = "Global" # id是全局作用域
def outside():
id = "Enclosing" # id是嵌套作用域
def inside():
id = "Local" # id是局部作用域
print(id) # Local
inside()
if __name__ == '__main__':
outside()
情景1
i = 11
def fun1():
i = 22 # 此处不会改变全局变量i的值
print(i)
if __name__ == '__main__':
fun1() # 22
print(i) # 11
情景2
num = 0
def fun2():
print(num) # UnboundLocalError: local variable 'num' referenced before assignment
num = 5 # 此处重新定义num,并覆盖了全局作用域的num,导致上一行代码没有找到num作用域而报错
if __name__ == '__main__':
fun2()
情景3
# 在默认情况下,在局部作用域或嵌套作用域中不能修改全局变量所引用的对象
# (如果引用的对象是可变类型的,可以修改对象的内容)
g = 20 #全局变量g是不可变类型对象
def f1():
# 重新定义了一个局部变量g,把全局变量g给屏蔽了
g = 19 # 与全局变量g内存地址不一样
def f2()
# 重新定义了一个局部变量g,把全局变量g给屏蔽了
g += 1 # 与全局变量g内存地址不一样
情景4
g2 = [3]
def f1():
# 重新定义了一个局部变量g2,把全局变量g给屏蔽了
g2 = [1] # 与全局变量g2内存地址不一样
def f2():
# 全局变量g2引用的对象是可变类型的,可以修改对象的内容
g2[0] = 8 # 与全局变量g2内存地址一样
情景5
“”“
如果想在局部作用域或嵌套作用域中修改全局变量所引用的对象,可以在局部作用域或
嵌套作用域中使用关键字global对变量进行声明,从而表明在局部作用域或嵌套作用域中不会再
重新定义一个新的同名变量,而是使用该名称的全局变量。
”“”
g = 20
def f3():
global g
g = 19 # 与全局变量g内存地址一样
print(g)
情景6
"""
流程控制语句和异常处理语句不会创建对应的作用域,因此,对于流程控制语句和异常处理语句中
定义的变量,在语句执行结束后仍然是可用的。
"""
if True:
temp = 18
print(temp) # 18
# -------------------------------
for item in [1, 2, 3]:
print(item)
print(item) # 3 循环结束后item仍然可用
# ------------------------------
try:
result = 5
except:
pass
print(result) # 5