Python函数的闭包问题

内部函数

>>> def func1():
...     print ('func1 running...')
...     def func2():
...             print ('func2 running...')
...     func2()
... 
>>> func1()
func1 running...
func2 running...
内部函数func2作用域都在外部函数func1作用域之内 

如果试图在外部函数的外部调用内部函数将会报错

>>> func2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'func2' is not defined

Python的闭包问题

如果试图在一个内部函数里对外部作用域(不包括外部函数的外部作用域)的变量进行引用,内部函数就会被认为是闭包

>>> def FuncX(x):
...     def FuncY(y):
...             return x*y
...     return FuncY

对于FuncY函数来说,对在FuncX函数的整个作用域(FuncY函数的非全局作用域的外部作用)的变量x进行引用,自此就可以说FuncY函数就是所谓的闭包

>>> f = FuncX(8)
>>> f
<function FuncY at 0x7f3a436fc2a8>
>>> type(f)
<type 'function'>
>>> f(10)
80
>>> FuncX(7)(8)
56

由于闭包本身是基于内部函数这一概念而来,所以不能在外部函数的外部作用域对内部函数进行调用

>>> FuncY(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'FuncY' is not defined

既然是基于内部函数这一概念而来,自然对于内部函数来说对引用外部函数作用域内的变量进行修改,将会启动解释器的屏蔽机制

>>> def Func1():
...     x = 233
...     def Func2():
...             x *=x
...             return x
...     return Func2()
... 
>>> Func1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in Func1
  File "<stdin>", line 4, in Func2
UnboundLocalError: local variable 'x' referenced before assignment

x*=x的左值此时是内部函数作用域里的变量,此时试图将没有定义的数据进行平方操作,因此报错

Python3之前的解决办法

应用容器类型(list,tuple之类的)存放外部函数作用域的变量从而不会被屏蔽机制屏蔽掉,因为容器类型不是存放在栈里面

>>> def Func1():
...     x = [233]
...     def Func2():
...             x[0] *= x[0]
...             return x[0]
...     return Func2()
... 
>>> Func1()
54289

Python3之后的解决办法——nonlocal关键字

>>> def Func1():
...     x = 233
...     def Func2():
...     nonlocal x
...             x *= x
...             return x
...     return Func2()
... 
>>> Func1()
54289

转载于:https://blog.csdn.net/ChangerJJLee/article/details/52598629

猜你喜欢

转载自blog.csdn.net/dta0502/article/details/80744775