课堂总结:
举两个例子:
x=5
def fun1():
x*=x
return x
fun1()
这个是报错的,因为x=5是全局变量,而fun1中x是局部变量,相当于内外层的关系,内层是不能获取外层的数据的。此时想引用外部变量,则需要加global,引用全局变量。如下:
x=5
def fun1():
global x
x *=x
print(x)
fun1()
第二个例子是加入一个内部函数(注意不是闭包!,闭包的外部返回值为一个函数,见后面的例题),相当于内层里面在加一层闭包空间,此时内层相当于内部层的‘‘全局变量’’。同样不能引用其数据
def fun1():
x= 5
def fun2():
x *=x
return x
return fun2()
print(fun1())
此时有两种修改办法,第一种是将x等于列表。列表则不会再栈当中,从而不存在全局不全局的问题
def fun1():
x= [5]
def fun2():
x[0] *=x[0]
return x[0]
return fun2()
print(fun1())
或者引用nonlocal,注意!与gobal的区别在gobal适用于真正的全局变量
def fun1():
x= 5
def fun2():
nonlocal x
x *=x
return x
return fun2()
print(fun1())
课后题
5.请问如何访问funIn()呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦')
return funIn
#注意,这里return是返回的funOut,而不是funIn
由于反回了函数而不是值,所以应该加俩括号,且这里第二个函数并没有返回值,所以不用print直接打印
##关于是否print的情况顺便作对比:
def fun1():
x= 5
def fun2():
nonlocal x
x *=x
return x
return fun2
print(fun1()())
def funOut():
def funIn():
print('宾果!你成功访问到我啦')
return funIn
funIn()()
从上面两个对比可已看出,首先,当最后的外包函数返回为一个函数,那么说明内函数为一闭包,此时要调用就必须要加俩括号。
而第一个闭包返回了一个值x,所以最后需要将其打印出来。
第二个闭包print了一个值,返回值为none,此时就只需要调用外包函数即可。
实际上就是内保函数是返回值还是打印值得问题
6.以下是“闭包”的一个例子,请你目测下会打印什么内容?,
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
答案:6
7
8
解析:首先看到外部返回一个函数,因此a=funx()=funY。然后funY()=x的返回值。x已经被定义为一个相对于外部空间的全局变量,因此每一次调用,x都会加1,数据不会被删除,而且会将外部x=5改变。所以每print一次,x值就会改变加一,所以是6.7.8