Python中没有块级作用,一共4个作用:LEGB
以 L -> E -> G -> B 的顺序去找作用域(优先找 L , 其次找 E … ),下面我们依次来区分一下各个作用域。
a = 1
def fun():
b = 2
print(b) # 局部变量
print(a) # 虽然局部没有变量 a,但是会输出全局变量 a。如果不注释下一条赋值语句,则报错。
# a = a + 1 # 报错:UnboundLocalError: local variable 'a' referenced before assignment 1️⃣
print(a) # 输出全局变量
1️⃣ 注意:Python ::编译函数::的定义体时,它判断 a 是局部变量,因为在函数中给 a ::赋值::了,所以函数中所有的变量 a 都属于局部变量
def outer():
a = 1
print(a)
def inner():
print(a) # 输出 1 2️⃣
# a = a + 1 # 报错:UnboundLocalError: local variable 'a' referenced before assignment
inner()
print(a)
2️⃣ 注意:不同作用域变量是不可见的,但是下级作用域可以对上级作用域的变量::只读可见::
作用:指定当前变量使用外部的全局变量
total = 0 # total是一个全局变量
def plus(arg1, arg2):
# global total # 使用 global 关键字声明此处的 total 引用外部全局的 total
total = arg1 + arg2 # total在这里是局部变量.
print("函数内局部变量total= ", total)
print("函数内的total的内存地址是: ", id(total))
return total
plus(10, 20)
print("函数外部全局变量total= ", total)
print("函数外的total的内存地址是: ", id(total))
作用:修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量
a = 1
print("函数outer调用之前全局变量a的内存地址: ", id(a))
def outer():
a = 2
print("函数outer调用之时闭包外部的变量a的内存地址: ", id(a))
def inner():
# nonlocal a # 注意这行,引用了 outer 函数的 a 变量。
a = 3
print("函数inner调用之后闭包内部变量a的内存地址: ", id(a))
inner()
print("函数inner调用之后,闭包外部的变量a的内存地址: ", id(a))
outer()
print("函数outer执行完毕,全局变量a的内存地址: ", id(a))
a = 1
def f1():
print(a) # 取全局变量 a = 1
def f2():
a = 2
f1()
f2()