在看之前先把这篇文章的global搞懂
先复习一下嵌套函数
内部函数,是无法被直接调用的,内部函数只能通过外部函数来调用
'''
嵌套函数
'''
#例1
def funA():
x=520
def funB():
x=880
print('in funB x=',x)
funB()#内部函数只能通过外部函数来调用
print('in funA x=',x)
'''
内部函数是无法被直接调用的
内部函数只能通过外部函数来调用
'''
'''
以下语句会报错
funB()
'''
funA()#in funB x= 880 in funA x= 520
首先对输出的结果要会判断,不会就是还没理解python作用域。
内部函数可以访问到外部函数的变量,但却无法修改外部函数变量的值,外部函数输出的x还是520.
例1中,内部函数外部函数,虽然都是x,但内部函数无法修改外部函数的值。
和global的例1是一样的感觉
使用nonlocal语句,在内部函数修改外部函数的变量
#例2
'''
使用nonlocal语句,在内部函数修改外部函数的变量
'''
def funA():
x=520
def funB():
nonlocal x
x=880
print('in funB x=',x)
funB()#内部函数只能通过外部函数来调用
print('in funA x=',x)
funA()#in funB x= 880 in funA x= 880
判断例3的代码是否会报错?
#例3
def funa():
x=5
def funb():
x+=1
print(x)
funb()
print(x)
funa()
'''
UnboundLocalError: local variable 'x' referenced before assignment
'''
例1,会报错,出错原因就是global,一样,虽然在外部函数找到了x,但当对x进行修改时,会把x当成局部变量,但在funb中没定义x,所以会出错。
在global那边文章中,我们说可以加global.在嵌套函数中可以使用nonlocal
#例4
def funa():
x=5
def funb():
nonlocal x
x+=1
print(x)
funb()
print(x)
funa()
有个神奇的是
#例5
def funa():
lst=[1,2]
se={10,20}
def funb():
lst.append(3)
print('内部函数中lst',lst)
se.add(30)
print('内部函数中se',se)
funb()
print('外部函数中lst',lst)
print('外部函数中se',se)
funa()
'''
内部函数中lst [1, 2, 3]
内部函数中se {10, 20, 30}
外部函数中lst [1, 2, 3]
外部函数中se {10, 20, 30}
'''
这没加nonlocal,这怎么可以修改外部函数的变量呢?这是因为列表,集合是容器变量,可以修改。
最后给出个两个代码,检验各位看官是否理解。
#例6
# 定义一个外部函数outer
def outer():
x = 2
# 定义一个内部函数inner
def inner():
# 在内部函数如何修改外部函数的局部变量
nonlocal x # 此时这里的x不再是新增的变量,而是外部的局部变量x
y = x + 1
print('y为',y)
x = 10
print('内部函数里的x等于',x)
inner()
print('外部函数里的x等于',x)
outer()
'''
y为 3
内部函数里的x等于 10
外部函数里的x等于 10
'''
最后,总结
python 里内嵌函数是可以修改外部环境里的变量的
关键是细节. 如果是简单变量类型, 那么不可以.如果相修改就是用nonlocal
但是如果是容器类变量, 则没问题了.
呕心沥血之作,希望有同样疑问的朋友,可以因为本篇节省点精力。
最后给个例子巩固。
#例7
# 定义一个外部函数outer
def outer():
a=11
b=22
x=[1,2,3]
def inner():
global c#如果想把内部变量传递到外部环境里,就必须在内部环境里声明为全局变量
c=a+b
#b=b+1#内部函数不能修改,简单型外部变量
x.append([4,5,6])
print('内部函数',a,b,c)
print('内部函数',x)
inner()
print('外部函数',a,b,c)
print('外部函数',x)
outer()
'''
内部函数 11 22 33
内部函数 [1, 2, 3, [4, 5, 6]]
外部函数 11 22 33
外部函数 [1, 2, 3, [4, 5, 6]]
'''