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实现Const详解
Jan 27 Python
Django与JS交互的示例代码
Aug 23 Python
Python3实现的画图及加载图片动画效果示例
Jan 19 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
May 11 Python
使用Python进行QQ批量登录的实例代码
Jun 11 Python
python获取指定字符串中重复模式最高的字符串方法
Jun 29 Python
pybind11在Windows下的使用教程
Jul 04 Python
Python无头爬虫下载文件的实现
Apr 02 Python
Python实现一个简单的递归下降分析器
Aug 01 Python
pytorch中F.avg_pool1d()和F.avg_pool2d()的使用操作
May 22 Python
Python Django ORM连表正反操作技巧
Jun 13 Python
Python编程中内置的NotImplemented类型的用法
Mar 23 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最常用的2种设计模式工厂模式和单例模式介绍
2012/08/14 PHP
PHP面向对象精要总结
2014/11/07 PHP
9个实用的PHP代码片段分享
2015/01/22 PHP
php实现将字符串按照指定距离进行分割的方法
2015/03/14 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
PHP 断点续传实例详解
2017/11/11 PHP
对YUI扩展的Gird组件 Part-2
2007/03/10 Javascript
jquery的ajax()函数传值中文乱码解决方法介绍
2012/11/08 Javascript
javascript中的window.location.search方法简介
2013/09/02 Javascript
jQuery.fn和jQuery.prototype区别介绍
2013/10/05 Javascript
浅谈javascript六种数据类型以及特殊注意点
2013/12/20 Javascript
用Webpack构建Vue项目的实践
2017/11/07 Javascript
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
2019/10/30 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
[52:36]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python 运算符 供重载参考
2009/06/11 Python
python中的对象拷贝示例 python引用传递
2014/01/23 Python
Python实现在Linux系统下更改当前进程运行用户
2015/02/04 Python
使用Python编写类UNIX系统的命令行工具的教程
2015/04/15 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
为什么入门大数据选择Python而不是Java?
2018/03/07 Python
详解python-图像处理(映射变换)
2019/03/22 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
解决pandas展示数据输出时列名不能对齐的问题
2019/11/18 Python
pyinstaller打包找不到文件的问题解决
2020/04/15 Python
Keras 快速解决OOM超内存的问题
2020/06/11 Python
python之语音识别speech模块
2020/09/09 Python
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
Agoda中文官网:安可达(低价预订全球酒店)
2021/01/18 全球购物
JAVA中运算符的分类及举例
2015/09/12 面试题
文明学生事迹材料
2014/01/29 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
专项资金申请报告
2015/05/15 职场文书
入党心得体会
2019/06/20 职场文书