# 函数的作用域
"""
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。
"""
# 四个作用域
"""
1、四个作用域的位置
2、全局作用域不能调用局部作用域的变量。
3、局部作用域不能修改全局作用的变量。
"""
# 示例1、四个作用域的位置
b = int(3.14) # int()在B(Built-in) 内建作用域,还有str() print()等等
g = 3 # 全局变量G(Global) 全局作用域
def foo1():
e = 4 # E(Enclosing) 嵌套作用域(也可以理解为闭包函数外的函数中,在函数嵌套中Foo1称为闭包函数,Foo称为闭包函数外的函数)
def bar1():
l = 5 # L (Local) 局部作用域
# 示例2、全局作用域不能调用局部作用域,下面代码报错捕获异常,打印异常信息
def foo2():
x = 10
try:
print(x)
except Exception as e:
print(e)
# 示例3
"""
1、局部作用域可以调用全局作用域
2、局部作用域不能修改全局作用的变量,会报错,捕获异常
报错信息‘local variable 'y' referenced before assignment’,说明这个变量在被创建之前就已经被调用了。
是因为作用域的查找范围,已经在局部作用域找变量y,但是在创建之前已经被调用,并非是因为修改。
不过也说明了局部作用域是无法修改全局作用域的,因为你声明同名变量python会认为你是局部变量,根本无法操作全局变量。
3、在局部作用域声明(使用global)全局作用域变量,可以修改。
4、在局部作用声明嵌套作用域(E)使用nonlocal,可以修改
"""
# 定义全局变量
y = 10
# 局部作用域可以调用全局作用域
def foo3():
print(y)
foo3()
# 局部作用域不能修改全局作用的变量
def foo4():
try:
y += 1
except Exception as e:
print(e)
else:
print(y)
foo4()
# 在局部作用域声明(使用global)全局作用域变量,可以修改
def foo5():
global y
y = 5
print(y)
foo5()
# 在局部作用声明嵌套作用域(E)使用nonlocal,可以修改
def foo6():
z = 20
def bar6():
nonlocal z
z = 15
print(z)
bar6()
print(z)
foo6()
"""总结
1、变量查找顺序 L –> E –> G –>B
2、只有模块,类,函数才能引入新作用域
3、对于一个变量,内部作用域先声明就会覆盖外部作用域,不声明直接使用,就会使用外部作用域
4、局部作用域要修改全局作用域变量时使用global,要修改嵌套作用域时使用nonlocal
"""