函数的作用域

Python中的作用域分为4种情况:

  1. L:local,局部作用域,即函数中定义的变量;
  2. E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
  3. G:global,全局变量,就是模块级别定义的变量
  4. B:built-in,系统固定模块里面的变量,比如int,bytearray等,搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>Python内置作用域 也就是LEGB
if True:
    x=3

print(x)


def f():
    y=10
f()
#print(y)
#函数有作用域,而if语句没有作用域
a=int(1.5)  #int变量是built-in
print(a)
count=5   #全局变量
def outer():
    print(count)   #打印了表示用的就是全局变量
#   count=4    全局变量不能修改,只能查看,否则会报错
# Traceback (most recent call last):
#   File "C:/Users/xiaojiaxin/PycharmProjects/fullstack1/week2/day6/函数作用域.py", line 28, in <module>
#     outer()
#   File "C:/Users/xiaojiaxin/PycharmProjects/fullstack1/week2/day6/函数作用域.py", line 24, in outer
#     print(count)
# UnboundLocalError: local variable 'count' referenced before assignment     Assignment:赋值,声明

outer()
# 5
#还有一种情况
count1=5
print(id(count1))
def outer1():
    count1=4   #这个不报错,因为这个count1和全局变量的count1是两个不同的变量!
    print(count1)
    print(id(count1))

outer1()
# 1685021024
# 4
# 1685020992
#另一种情况
# count2=5
# def outer2():
#     count2+=1    #同样会报错,因为count2+=1等价于count2=count2+1,还是用到全局变量的值,全局变量的值是不能更改的
#     print(count2)
# # File "C:/Users/xiaojiaxin/PycharmProjects/fullstack1/week2/day6/函数作用域.py", line 60, in outer2
# #     count2+=1
# # UnboundLocalError: local variable 'count2' referenced before assignment
#
# outer2()
#要想在函数里修改局部变量,要声明Global变量
count3=5
def outer3():
    global count3   #声明以后就不报错了,可以进行任意的修改
    count3+=1
    print(count3)
outer3()
# 6

嵌套函数修改局部变量,要声明nonlocal变量

def outer4():
    count4=5
    def inner():
        nonlocal count4   #使用在父级函数中的局部变量,使用nonlocal关键字,作用同global关键字一样
        count4+=2
        print(count4)
    inner()

outer4()
# 7

小结: 1.变量查找顺序LEGB 2.只有模块、类、函数才能引入新作用域; 3.对于一个变量,内部作用域先声明就会覆盖外部作用域,不声明直接使用,就会使用外部作用域的变量; 4.内部作用域要修改外部作用域变量时,全局变量要使用global关键字,嵌套作用域变量使用nonlocal关键字,nonlocal是Python3新增的关键字,有了这个关键字,就能完美的实现闭包了。

大家对内容有任何问题,欢迎留言,定在第一时间解答,谢谢大家!