一 变量作用域

python变量作用域一般有4种,如下

1. Local(局部变量)
  • Local(局部变量):暂时的存在,依赖于创建该局部作用域的函数。函数存,则局部变量存,函数亡,则局部变量亡。如下
#局部作用域
def fun():
    b = 2
    print(b)#输出2
    
fun()
print(b)#报错
>>>
2
Traceback (most recent call last):
  File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 14, in <module>
    print(b)
NameError: name 'b' is not defined

2. Enclosed(嵌套)
  • Enclosed(嵌套):一般是在函数中嵌套函数的时候,外层函数的变量作用域。
#Enclosed(嵌套)作用域
def fun1():
    b = 2
    print("这是fun1打印的:", b)
    def fun2():
        print("这是fun2打印的:", b)
    return fun2

temp = fun1()#调用fun1
temp()#调用fun2

在这里函数fun2里面并没有定义变量b,但是它能够引用外层函数fun1定义的b变量,此时变量b的作用域就是Enclosed. 结果如下

>>>
这是fun1打印的: 2
这是fun2打印的: 2

3. Global(全局)
  • Global(全局):一般模块文件顶层声明的变量具有全局作用域,从外部来看,模
    块的全局变量就是一个模块对象的属性,仅限于单个模块文件中。
#Global(全局)作用域
a = 2
def fun1():
    print("这是fun1打印的:", a)

fun1()
print(a)
>>>
这是fun1打印的: 2
2

4. Built-in(内置)
  • Built-in(内置):解释器内置的变量,比如int, str等。

二 变量使用规则

python中变量的使用遵循上面的四种规则,即LEGB规则,如下
在这里插入图片描述

  • 创建变量时从上往下创建,搜索变量时从下往上搜索。
  • 创建变量时,下层变量会覆盖上层同名变量,但不会改变上层变量的值,除非使用gloable和nonlocal关键字声明

三 变量的修改

1. global修改全局变量

一般全局变量一经定义后几乎是不用改的,也不允许在局部修改全局变量,除非使用Global关键字声明。如下

a = "我是全局变量"
def fun1():
    a += "但是是修改后的全局变量"#修改全局变量
    print(a)
    
fun1()
>>>
UnboundLocalError: local variable 'a' referenced before assignment

可以看到,当我们试图在函数fun1创建的局部作用域内改变全局变量a就会报错,但如果在修改之前使用global关键字声明时,就会正常修改外部的全局变量a,如下

a = "我是全局变量"
def fun1():
    global a    #使用global声明
    a += ",但是是修改后的全局变量"#修改全局变量
    print(a)

print(a)#fun1函数修改前
fun1()
print(a)#fun1函数修改后
>>>
我是全局变量
我是全局变量,但是是修改后的全局变量
我是全局变量,但是是修改后的全局变量

2. nonlocal修改外层函数变量

在函数中嵌套函数时,嵌套在里面的函数创建的作用域内一般也是不允许改变外层函数变量的值的,除非是nonlocal关键字声明。如下

#不使用nonocal声明,修改外层函数变量值
def fun1():
    a = "我是fun1的变量"

    def fun2():
        a += ",但是我是修改后的"
        print(a)
    return fun2

temp = fun1()#调用fun1
temp()#调用fun2
>>>
UnboundLocalError: local variable 'a' referenced before assignment

可以看到,报错和在函数内不使用global修改全局变量报的错是一样的,当使用nonlocal声明后再修改就不会报错了,如下

#使用nonocal声明,修改外层函数变量值
def fun1():
    a = "我是fun1的变量"
    print(a)#修改前
    def fun2():
        nonlocal a  #使用nonlocal声明
        a += ",但是我是修改后的"
        print(a)#修改后
    return fun2

temp = fun1()#调用fun1
temp()#调用fun2
>>>
我是fun1的变量
我是fun1的变量,但是我是修改后的

可以看到是正常修改的。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐