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


Posted in Python onMay 17, 2019

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 相关文章推荐
Python编程中运用闭包时所需要注意的一些地方
May 02 Python
详解python之简单主机批量管理工具
Jan 27 Python
Python实现的读写json文件功能示例
Jun 05 Python
Django开发中的日志输出的方法
Jul 02 Python
Python多线程编程之多线程加锁操作示例
Sep 06 Python
python复制列表时[:]和[::]之间有什么区别
Oct 16 Python
详解django的serializer序列化model几种方法
Oct 16 Python
python使用tomorrow实现多线程的例子
Jul 20 Python
Python实现代码统计工具
Sep 19 Python
python根据时间获取周数代码实例
Sep 30 Python
python调用有道智云API实现文件批量翻译
Oct 10 Python
详解Python调用系统命令的六种方法
Jan 28 Python
学习python分支结构
May 17 #Python
python pygame实现方向键控制小球
May 17 #Python
基于Numpy.convolve使用Python实现滑动平均滤波的思路详解
May 16 #Python
Python实现Linux监控的方法
May 16 #Python
计算机二级python学习教程(3) python语言基本数据类型
May 16 #Python
Python实现爬取亚马逊数据并打印出Excel文件操作示例
May 16 #Python
Python实现的文轩网爬虫完整示例
May 16 #Python
You might like
php字符串截取问题
2006/11/28 PHP
phpMyAdmin出现无法载入 mcrypt 扩展,请检查PHP配置的解决方法
2012/03/26 PHP
php如何解决无法上传大于8M的文件问题
2014/03/10 PHP
kohana框架上传文件验证规则写法示例
2014/07/14 PHP
推荐几款用 Sublime Text 开发 Laravel 所用到的插件
2014/10/30 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
Yii2 批量插入、更新数据实例
2017/03/15 PHP
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
SyntaxHighlighter语法高亮插件使用说明
2011/08/14 Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
2013/03/29 Javascript
浅析LigerUi开发中谨慎载入common.css文件
2013/07/09 Javascript
JS简单实现多级Select联动菜单效果代码
2015/09/06 Javascript
js实现对ajax请求面向对象的封装
2016/01/08 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
vue实现点击图片放大效果
2017/08/15 Javascript
详解Vue Elememt-UI构建管理后台
2018/02/27 Javascript
微信小程序日历组件使用方法详解
2018/12/29 Javascript
vue-router 2.0 跳转之router.push()用法说明
2020/08/12 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
[02:47]3.19DOTA2发布会 国服成长历程回顾
2014/03/25 DOTA
Django 2.0版本的新特性抢先看!
2018/01/05 Python
Python函数参数匹配模型通用规则keyword-only参数详解
2019/06/10 Python
Flask配置Cors跨域的实现
2019/07/12 Python
python实现证件照换底功能
2019/08/20 Python
Numpy的简单用法小结
2019/08/28 Python
python智联招聘爬虫并导入到excel代码实例
2019/09/09 Python
vim自动补全插件YouCompleteMe(YCM)安装过程解析
2019/10/21 Python
python 基于pygame实现俄罗斯方块
2021/03/02 Python
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
高中化学教学反思
2014/01/13 职场文书
黄金搭档广告词
2014/03/21 职场文书
安全保证书怎么写
2015/02/28 职场文书
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript
正则表达式拆分url实例代码
2022/02/24 Java/Android
高并发下Redis如何保持数据一致性(避免读后写)
2022/03/18 Redis