138 lines
4.1 KiB
Python
138 lines
4.1 KiB
Python
# 变量的作用域(scope)指的是一个变量在程序中可以被访问的范围。Python中的变量作用域遵循LEGB规则,即按照以下顺序查找变量:
|
|
|
|
# L (Local):局部作用域
|
|
# E (Enclosing):嵌套作用域
|
|
# G (Global):全局作用域
|
|
# B (Built-in):内置作用域
|
|
# 基本特点
|
|
|
|
# 局部作用域:函数内部定义的变量,只能在函数内部访问
|
|
# 嵌套作用域:嵌套函数中外层函数的变量对内层函数可见
|
|
# 全局作用域:模块级别定义的变量,在整个模块中可见
|
|
# 内置作用域:Python内置的函数和变量
|
|
|
|
|
|
# 定义一个外层函数outer_function
|
|
def outer_function():
|
|
# 在外层函数中定义一个变量y,并赋值为20
|
|
y = 20
|
|
print(f"外层函数中的y: {y}")
|
|
|
|
# 在外层函数内部定义一个内层函数inner_function
|
|
def inner_function():
|
|
# 内层函数可以访问外层函数的变量y
|
|
print(f"内层函数访问外层变量y: {y}")
|
|
# 预期输出: 内层函数访问外层变量y: 20
|
|
|
|
# 调用内层函数
|
|
inner_function()
|
|
|
|
# 在外层函数中再次打印y
|
|
print(f"外层函数中y的值: {y}")
|
|
|
|
|
|
# 调用外层函数
|
|
outer_function()
|
|
|
|
|
|
# 全局作用域的修改
|
|
# 在嵌套作用域中,内层函数可以“读取”外层函数的变量,但如果要“直接修改”外层变量,会遇到限制。
|
|
# 默认情况下,如果你在内层函数中为某个变量赋值,这个变量会被视为“局部变量”,而不是外层的同名变量。这种行为可能会导致UnboundLocalError错误
|
|
|
|
|
|
def outer():
|
|
num = 10 # 外层变量
|
|
|
|
def inner():
|
|
# 尝试直接修改外层变量,会报错
|
|
try:
|
|
num += 1 # 内层函数会认为num是自己的局部变量
|
|
except UnboundLocalError as e:
|
|
print(f"错误: {e}")
|
|
|
|
inner()
|
|
print(f"最终num: {num}")
|
|
|
|
|
|
outer()
|
|
# 输出: 错误: local variable 'num' referenced before assignment
|
|
# 最终num: 10
|
|
|
|
# 在Python中,如果想在函数内部修改全局变量,必须用global关键字声明该变量属于全局作用域,否则Python会将其当作一个新的局部变量,导致修改的只是函数内部的“影子”变量,而不是外部真正的全局变量。
|
|
|
|
# 总结:
|
|
|
|
# 只读全局变量时可直接在函数内引用;
|
|
# 想在函数内修改全局变量值,必须加global关键字;
|
|
# 否则会创建/修改局部变量,不会影响全局作用域中的变量值。
|
|
|
|
global_var = 100
|
|
|
|
|
|
def modify_global():
|
|
global global_var
|
|
global_var += 10
|
|
print(f"函数内部修改后的global_var{global_var}") # 110
|
|
|
|
|
|
modify_global()
|
|
print(f"函数外部的global_var{global_var}") # 110
|
|
|
|
|
|
# nonlocal关键字的高级用法
|
|
# 在嵌套函数中修改外层嵌套函数的变量
|
|
|
|
print("----------nonlocal--------------------")
|
|
|
|
|
|
def complex_outer():
|
|
outer_var = "外层变量"
|
|
count = 0
|
|
|
|
def middle_function():
|
|
middle_var = "中层变量"
|
|
|
|
def inner_function():
|
|
nonlocal outer_var, count
|
|
outer_var = "被内层函数修改"
|
|
count += 1
|
|
print(f"内层函数修改外层变量: {outer_var}")
|
|
print(f"内层函数修改计数器: {count}")
|
|
|
|
inner_function()
|
|
print(f"中层函数检查中层变量: {middle_var}")
|
|
|
|
middle_function()
|
|
print(f"外层函数检查外层变量: {outer_var}")
|
|
print(f"外层函数检查计数器: {count}")
|
|
|
|
|
|
complex_outer()
|
|
|
|
|
|
# 定义一个全局变量
|
|
conflict_var = "全局变量"
|
|
print(f"初始全局变量: {conflict_var}")
|
|
|
|
|
|
# 定义一个函数来演示变量名冲突
|
|
# 这是一个作用域冲突导致的语法错误。
|
|
# 解决方案 将 global 声明放在函数开头(推荐)
|
|
|
|
|
|
# def conflict_demo():
|
|
# # 在函数内部定义同名变量
|
|
# conflict_var = "局部变量"
|
|
# print(f"函数内部局部变量: {conflict_var}")
|
|
|
|
# # 如果要访问全局变量,需要使用global关键字
|
|
# global conflict_var
|
|
# print(f"使用global后的全局变量: {conflict_var}")
|
|
|
|
|
|
# # 调用函数
|
|
# conflict_demo()
|
|
|
|
# # 检查全局变量
|
|
# print(f"函数外部全局变量: {conflict_var}")
|