详解python函数的闭包问题(内部函数与外部函数详述)

所属分类: 脚本专栏 / python 阅读数: 1946
收藏 0 赞 0 分享

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的左值此时是内部函数作用域里的变量,此时试图将没有定义的数据进行平方操作,因此报错

>>> def Func1():
...   x = 233
...   def Func2():
...       x = 321
...       return x
...   return Func2()
... 
>>> Func1()
321

内部函数创建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

以上所述是小编给大家介绍的python函数的闭包问题详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

更多精彩内容其他人还在看

Python调用C/C++的方法解析

这篇文章主要介绍了Python调用C/C++的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

学习Python爬虫的几点建议

这篇文章主要介绍了学习Python爬虫的几点建议,对新手学习爬虫有很大的帮助,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

Python创建临时文件和文件夹

这篇文章主要介绍了Python如何创建临时文件和文件夹,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

浅析Python 序列化与反序列化

这篇文章主要介绍了Python 序列化与反序列化的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

8种常用的Python工具

这篇文章主要介绍了8种常用的Python工具,帮助大家更好的学习Python,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

python爬虫使用requests发送post请求示例详解

这篇文章主要介绍了python爬虫使用requests发送post请求示例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Python结合Window计划任务监测邮件的示例代码

这篇文章主要介绍了Python结合Window计划任务监测邮件的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Python用来做Web开发的优势有哪些

这篇文章主要介绍了Python用来做Web开发的优势有哪些,文中讲解非常细致,帮助大家更好的理解和学习Python,感兴趣的朋友可以了解下
收藏 0 赞 0 分享

如何解决pycharm调试报错的问题

在本篇内容里小编给大家整理的是一篇关于如何解决pycharm调试报错的问题文章,需要的朋友们可以学习参考下。
收藏 0 赞 0 分享

基于logstash实现日志文件同步elasticsearch

这篇文章主要介绍了基于logstash实现日志文件同步elasticsearch,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多