Python、Javascript中的闭包比较


Posted in Python onFebruary 04, 2015

同为脚本语言,python和Javascript具有相似的变量作用域,不像php,函数的内部的所有变量和外部都是隔绝的,也就是说,函数要想处理其外部的数据,必须使用参数把需要处理的数据传递进来(使用global关键词这里不讨论),而python和Javascript不同,如果在函数声明变量,它会逐级网上查找,直到返回着个值或者未定义。

那么这样说,python的闭包应该很简单了,像javascript一样,我们编写类似的代码:

def func1():
    a = 1
    def func2():
        a = a + 1
        return a
    return func2
re=func1()
print re()
print re()

但是,实际情况是,结果并没有出现我们预期中的打印出2和3,反而出现了这样的错误:”UnboundLocalError: local variable ‘a' referenced before assignment”(局部变量a赋值之前被引用)。为什么会出现这样的问题,我们先看看js是如果实现这个闭包的:

<script>
 function func1(){
 var a=1;
  function func2(){
  a=a+1;
  return a;
  }
 return func2;
 }
re=func1();
console.log(re());
console.log(re());
</script>

上面这段代码的运行结果如我们所料,输入2和3。注意一下这段程序的第5行,如果我在前面加上一个var,这段程序运行的结果是什么样的呢?最终结果是输入了两个“NaN”,在火狐的开发者平台上,找到了关于var这样的描述:

Declares a variable, optionally initializing it to a value.
The scope of a variable declared with var is the enclosing function or, for variables declared outside a function, the global scope (which is bound to the global object).

意思是说,var是用来声明局部变量的,上面的例子中,如果用var a=a+1,这时候的a就已经是func2中的局部变量,而不会从func1中继承,所以最后会出现NaN的结果。

让我们回到python的这个闭包上来,这个错误提示的意思也是说a是个局部变量,实际上,python规定所有在赋值语句左面的变量都是局部变量,这个a在等号左边,所以成了一个局部的变量,导致我访问不到func1中的a。这个问题怎么解决呢?如果是在python3.0以上,在a=a+1之前,可以用nonloacal a来指定a不为局部变量。3.0以下的版本不支持nonloacal关键字,我们可以这样做:

def func1():
    a = [1]
    def func2():
        a[0] = a[0] + 1
        return a[0]
    return func2
re=func1()
print re()
print re()

运行结果如我们所料,打印出了2和3。从python和Javascript闭包的例子,要了解python和js变量声明,变量作用域的相似和不同之处。

Python 相关文章推荐
使用Python抓取模板之家的CSS模板
Mar 16 Python
修改Python的pyxmpp2中的主循环使其提高性能
Apr 24 Python
玩转python爬虫之爬取糗事百科段子
Feb 17 Python
Python中遇到的小问题及解决方法汇总
Jan 11 Python
Python只用40行代码编写的计算器实例
May 10 Python
Python 装饰器使用详解
Jul 29 Python
python在ubuntu中的几种安装方法(小结)
Dec 08 Python
python将字典内容存入mysql实例代码
Jan 18 Python
Python实现的文本对比报告生成工具示例
May 22 Python
解决Python pandas plot输出图形中显示中文乱码问题
Dec 12 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
Apr 24 Python
解决python调用自己文件函数/执行函数找不到包问题
Jun 01 Python
线程和进程的区别及Python代码实例
Feb 04 #Python
Python中使用PIPE操作Linux管道
Feb 04 #Python
Python实现在Linux系统下更改当前进程运行用户
Feb 04 #Python
使用Python编写Linux系统守护进程实例
Feb 03 #Python
Python中使用select模块实现非阻塞的IO
Feb 03 #Python
Python异常学习笔记
Feb 03 #Python
Python中的迭代器漫谈
Feb 03 #Python
You might like
php 全文搜索和替换的实现代码
2008/07/29 PHP
php checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
分享常见的几种页面静态化的方法
2015/01/08 PHP
php连接oracle数据库的方法(测试成功)
2016/05/26 PHP
php获取ip及网址的简单方法(必看)
2017/04/01 PHP
Ext面向对象开发实践(续)
2008/11/18 Javascript
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
jquery利用ajax调用后台方法实例
2013/08/23 Javascript
Javascript基础 函数“重载” 详细介绍
2013/10/25 Javascript
js 异步操作回调函数如何控制执行顺序
2013/12/24 Javascript
利用Jquery实现可多选的下拉框
2014/02/21 Javascript
用原生js做个简单的滑动效果的回到顶部
2014/10/15 Javascript
jQuery中parent()方法用法实例
2015/01/07 Javascript
详解Javascript百度地图接口开发文档中的类和方法
2017/02/07 Javascript
Vuejs仿网易云音乐实现听歌及搜索功能
2017/03/30 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
利用Three.js如何实现阴影效果实例代码
2017/09/26 Javascript
基于vue cli重构多页面脚手架过程详解
2018/01/23 Javascript
详解react-refetch的使用小例子
2019/02/15 Javascript
微信小程序嵌入腾讯视频源过程详解
2019/08/08 Javascript
layui表格 列自动适应大小失效的解决方法
2019/09/06 Javascript
微信小程序自定义弹出模态框禁止底部滚动功能
2020/03/09 Javascript
浏览器JavaScript调试功能无法使用解决方案
2020/09/18 Javascript
Python排序搜索基本算法之插入排序实例分析
2017/12/11 Python
python之matplotlib学习绘制动态更新图实例代码
2018/01/23 Python
Windows下anaconda安装第三方包的方法小结(tensorflow、gensim为例)
2018/04/05 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
使用OpenCV实现仿射变换—缩放功能
2019/08/29 Python
Python 实现打印单词的菱形字符图案
2020/04/12 Python
如何真正的了解python装饰器
2020/08/14 Python
美国咖啡批发网站:Coffee.org
2017/06/29 全球购物
红色连衣裙精品店:Red Dress Boutique
2018/08/11 全球购物
自我评价范文点评
2013/12/04 职场文书
预备党员表决心书
2014/03/11 职场文书
Python入门之使用pandas分析excel数据
2021/05/12 Python
js前端面试常见浏览器缓存强缓存及协商缓存实例
2022/06/21 Javascript