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运行效率的方法之间的对比
Apr 03 Python
用Python的Flask框架结合MySQL写一个内存监控程序
Nov 07 Python
浅谈Python实现2种文件复制的方法
Jan 19 Python
Python处理文本换行符实例代码
Feb 03 Python
python代码过长的换行方法
Jul 19 Python
Python 读写文件的操作代码
Sep 20 Python
Django实现一对多表模型的跨表查询方法
Dec 18 Python
Python 异步协程函数原理及实例详解
Nov 13 Python
python垃圾回收机制(GC)原理解析
Dec 30 Python
pytorch中图像的数据格式实例
Feb 11 Python
python 连续不等式语法糖实例
Apr 15 Python
基于Python组装jmx并调用JMeter实现压力测试
Nov 03 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 得到根目录的 __FILE__ 常量
2008/07/23 PHP
PHP提示Warning:phpinfo() has been disabled函数禁用的解决方法
2014/12/17 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
2017/06/17 PHP
使用PHPUnit进行单元测试并生成代码覆盖率报告的方法
2019/03/08 PHP
Laravel5.1 框架表单验证操作实例详解
2020/01/07 PHP
js类 from qq
2006/11/13 Javascript
在IE中调用javascript打开Excel的代码(downmoon原作)
2007/04/02 Javascript
JavaScript 快捷键设置实现代码
2009/03/13 Javascript
jQuery scroll事件实现监控滚动条分页示例
2014/04/04 Javascript
Node.js中使用计时器定时执行函数详解
2014/08/15 Javascript
手机号码,密码正则验证
2014/09/04 Javascript
Js+php实现异步拖拽上传文件
2015/06/23 Javascript
JS判断iframe是否加载完成的方法
2016/08/03 Javascript
angularjs实现下拉列表的选中事件示例
2017/03/03 Javascript
JS去掉字符串前后空格或去掉所有空格的用法
2017/03/25 Javascript
JQuery 获取Dom元素的实例讲解
2017/07/08 jQuery
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
前端面试知识点目录一览
2019/04/15 Javascript
js实现上传按钮并显示缩略图小轮子
2020/05/04 Javascript
python读写ini文件示例(python读写文件)
2014/03/25 Python
python学习笔记之调用eval函数出现invalid syntax错误问题
2015/10/18 Python
pandas DataFrame 删除重复的行的实现方法
2019/01/29 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
Python根据URL地址下载文件并保存至对应目录的实现
2020/11/15 Python
HTML5实现自带进度条和滑块滑杆效果
2018/04/17 HTML / CSS
Sandro法国官网:法国成衣品牌
2019/08/28 全球购物
感恩母亲节活动方案
2014/03/04 职场文书
2014年开学第一课活动方案
2014/03/06 职场文书
党支部公开承诺践诺书
2014/03/28 职场文书
机械专业应届毕业生自荐书
2014/06/12 职场文书
2014年党务公开工作总结
2014/12/09 职场文书
金正昆讲礼仪观后感
2015/06/11 职场文书
工作简报格式范文
2015/07/21 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书
vue实现可拖拽的dialog弹框
2021/05/13 Vue.js