python函数的闭包问题(内嵌函数)
1
2
3
4
5
6
7
8
9
|
>>> def func1():
... print ( 'func1 running...' )
... def func2():
... print ( 'func2 running...' )
... func2()
...
>>> func1()
func1 running...
func2 running...
|
内部函数func2作用域都在外部函数func1作用域之内
如果试图在外部函数的外部调用内部函数将会报错
1
2
3
4
|
>>> func2()
traceback (most recent call last):
file "<stdin>" , line 1 , in <module>
nameerror: name 'func2' is not defined
|
关于python的闭包问题
如果试图在一个内部函数里对外部作用域(不包括外部函数的外部作用域)的变量进行引用,内部函数就会被认为是闭包
1
2
3
4
|
>>> def funcx(x):
... def funcy(y):
... return x * y
... return funcy
|
对于funcy函数来说,对在funcx函数的整个作用域(funcy函数的非全局作用域的外部作用)的变量x进行引用,自此就可以说funcy函数就是所谓的闭包
1
2
3
4
5
6
7
8
9
|
>>> f = funcx( 8 )
>>> f
<function funcy at 0x7f3a436fc2a8 >
>>> type (f)
< type 'function' >
>>> f( 10 )
80
>>> funcx( 7 )( 8 )
56
|
由于闭包本身是基于内部函数这一概念而来,所以不能在外部函数的外部作用域对内部函数进行调用
1
2
3
4
|
>>> funcy( 8 )
traceback (most recent call last):
file "<stdin>" , line 1 , in <module>
nameerror: name 'funcy' is not defined
|
既然是基于内部函数这一概念而来,自然对于内部函数来说对引用外部函数作用域内的变量进行修改,将会启动解释器的屏蔽机制
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> 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的左值此时是内部函数作用域里的变量,此时试图将没有定义的数据进行平方操作,因此报错
1
2
3
4
5
6
7
8
9
|
>>> def func1():
... x = 233
... def func2():
... x = 321
... return x
... return func2()
...
>>> func1()
321
|
内部函数创建x变量并且屏蔽外部函数作用域内的x变量
python3之前的解决办法
应用容器类型(list,tuple之类的)存放外部函数作用域的变量从而不会被屏蔽机制屏蔽掉,因为容器类型不是存放在栈里面
1
2
3
4
5
6
7
8
9
|
>>> def func1():
... x = [ 233 ]
... def func2():
... x[ 0 ] * = x[ 0 ]
... return x[ 0 ]
... return func2()
...
>>> func1()
54289
|
python3之后的解决办法:nonlocal关键字
1
2
3
4
5
6
7
8
9
10
|
>>> def func1():
... x = 233
... def func2():
... nonlocal x
... x * = x
... return x
... return func2()
...
>>> func1()
54289
|
以上所述是小编给大家介绍的python函数的闭包问题详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:https://blog.csdn.net/ChangerJJLee/article/details/52598629