让我们先看看代码。 不是有很多疑问吗
defscope_test(:defdo_local ) ) :
spam='local spam '
defdo_nonlocal () :
nonlocal spam
spam='nonlocal spam '
defdo_global () :globalspam
spam=' global spam ' spam=' test spam ' do _ local () print )、afterlocalassignment: )、spam ) ) )。
do_nonlocal () print )、afternonlocalassignment: )、spam ) )。
do_global () print )、afterglobalassignment: )、spam ) )。
scope_test () print )、' inglobalscope: '、spam )和' '的输出:
自适应3360测试间隔
afternonlocalassignment 3360 non local spam
afterglobalassignment 3360非本地空间
全局空间:全局空间“”
不知道第三个理由时,补充
x=0defouter () :
x=1
definner(:globalx
x=2
print(inner:x ) ) ) ) ) ) ) ) ) ) )。
inner () print )、outer: )、x ) )。
outer () print('global: ',x ) inner :2 # outer :1 # global :
如果局部变量与全局变量名称相同,则优先调用局部变量,因此解决了上述问题
首先,理解全局变量和局部变量
1 .全局变量和局部变量的区别在于作用域,全局变量在整个py文件中声明,可以在全局范围内使用; 局部变量在一个函数内部声明,只能在函数内部使用,超出使用范围(函数外部)时会出现错误
A=100 #全局变量通常用大写字母表示
deffunc(:
a=50 #局部变量通常用小写字母表示
打印(aa ) )。
func () #150
打印(a ) #100
print(a ) #错误消息name error : name ' a ' is not defined,表示局部变量只能在函数中使用
2 .在函数内部,如果局部变量与全局变量名称相同,则优先调用局部变量
A=100
deffunc(:
A=250
print(a ) print(a ) #打印所有变量100
func(#局部变量250
3 .如果要在函数内部更改全局变量,则必须在前面加上global关键字,执行函数后,全局变量的值也会发生变化
A=100
deffunc(:globala
A=200
打印(a )打印(a ) #打印全局变量100
func(#局部变量200
print(a ) #变更后的全局变量200
4 .如果全局变量是列表类型(如果全局变量是可变对象,则可以处理内部元素),则可以使用list的列表方法修改列表,而不使用global进行声明
list _1=[ 1,2,56,' list']defchangeList () :
list_1. append (“over”(print ) list _1) ) ) ) ) ) ) )。
changelist (# [ 1,2,56,' list ',' over'] ' )
print(list_1) # [ 1,2,56,' list ',' over']
5 .如果函数中有global关键字,则变量本质上是全局变量,是可读且可赋值的
NAME='nicholas '
print(1,NAME ) defchange_NAME ) ) :globalNAME
NAME='niubi '
print('change_NAME ',name )。
change_NAME () print(2),NAME ) #具有global,它定义的是全局变量,可以赋值或更改值
请注意全球的位置。 如果global需要更改全局变量,则此处的global不能位于name='nick '下
6 .如果全局变量是不可变对象(非list ),则无法在函数中修改全局变量,但如果要修改,可以使用全局变量
count=0defglobal_test () :
count=1
打印(计数)
global_test()#UnboundLocalError: local variable 'count' referenced before assignment
nonlocal
python变量引用顺序:从当前作用域开始寻找变量,如果没找到就往上一层作用域寻找,没找到就再上一层......
即:当前作用域局部变量->外层作用域变量->再外层作用域变量->......->当前模块全局变量->pyhton内置变量
global:全局变量
nonlocal:外层嵌套函数的变量
使用总结:
1、局部作用域改变全局变量用global, global同时还可以定义新的全局变量
2、内层函数改变外层函数变量用nonlocal, nonlocal不能定义新的外层函数变量,只能改变已有的外层函数变量(外层直到全局作用域的下一层都没有,会报错),同时nonlocal不能改变全局变量
当没有nonlocal时
a = 10 #a1 当前模块全局变量
defouter():
a= 9 #a2 当前outter作用域局部变量
definner():
a= 8 #a3 当前inner作用域局部变量
print(a) #a3 8, 在inner的局部作用域中找到了a3
inner() #inner()函数结束,a3作为inner局部变量被释放
print(a) #a2 9,在outer局部作用域中找到a2
outer() #outer()函数结束,a2作为outer局部变量被释放
a'''8
9
10'''
用于在内层函数中改变外层函数变量
a = 10 #a1 当前模块全局变量
defouter():
a= 9 #a2 outer局部变量
definner():
nonlocal a
a= 8 #a3 既是inner局部变量,又是外层outer局部变量
print(a) #a3 8,在inner的局部作用域中找到了a3
inner() #inner()函数结束,a3作为外层变量(outer局部变量)被保留成为a2
print(a) #a2 8,在outer局部作用域中找到a2(在inner中被改变)
outer() #outer()函数结束,a2作为outer局部变量被释放
print(a) #a1 10,在当前模块全局作用域中找到了a1
'''输出
8
8
10'''
如果在外层没有找到变量a,则会继续在再外层寻找,直到全局作用域的下一层为止
a = 10 #a1 当前模块全局变量
defouter2():
a= 9 #a2 outer2作用域局部变量
print(a) #a2 9,还未被a3改变
defouter1():print(a) #a2 9,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(还未被a3改变)
definner():
nonlocal a
a= 0 #a3 既是inner局部变量,又是再外层outer2作用域变量
print(a) #a3 0, 找到inner局部变量a3
inner() #inner()函数结束,a3作为外层变量(outer2局部变量)被保留成为a2
print(a) #a2 0,在outer1中没找到局部变量a,则寻找外层(outer2)变量a2(被a3改变)
outer1()print(a) #a2 0, 在outer1中找到outer1局部变量a2(被a3改变)
outer2()print(a) #a1 10,在当前模块全局作用域中找到了a1
'''输出
9
9
0
0
0
10'''
全局变量不是外层变量,不被nonlocal寻找
a = 10 #a1 当前模块全局变量
defouter():definner():
nonlocal a#在当前作用域外层即outer局部作用域中没找到outer局部变量a,outer外层为全局作用域,nonlocal不继续寻找,报错
a = 8
print(a)
inner()print(a)
outer()print(a) #a1 10,在当前模块全局作用域中找到了a1
'''输出
SyntaxError: no binding for nonlocal 'a' found'''
注意:使用global关键字修饰的变量之前可以并不存在,而使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存在