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用于url解码和中文解析的小脚本(python url decoder)
Aug 11 Python
wxpython学习笔记(推荐查看)
Jun 09 Python
python实现查找excel里某一列重复数据并且剔除后打印的方法
May 26 Python
python中的迭代和可迭代对象代码示例
Dec 27 Python
python实现m3u8格式转换为mp4视频格式
Feb 28 Python
django 发送手机验证码的示例代码
Apr 25 Python
python3中获取文件当前绝对路径的两种方法
Apr 26 Python
pycharm的console输入实现换行的方法
Jan 16 Python
flask框架路由常用定义方式总结
Jul 23 Python
Python多线程通信queue队列用法实例分析
Mar 24 Python
Python实现Wordcloud生成词云图的示例
Mar 30 Python
利用Selenium添加cookie实现自动登录的示例代码(fofa)
May 08 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数组遍历知识汇总(包含遍历方法、数组指针操作函数、数组遍历测速)
2014/07/05 PHP
php自定义函数实现二维数组排序功能
2016/07/20 PHP
PHP检查网站是否宕机的方法示例
2017/07/24 PHP
laravel 事件/监听器实例代码
2019/04/12 PHP
在laravel框架中实现封装公共方法全局调用
2019/10/14 PHP
用JQuery调用Session的实现代码
2010/10/29 Javascript
一个级联菜单代码学习及removeClass与addClass的应用
2013/01/24 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
2013/04/16 Javascript
javascript弹出层输入框(示例代码)
2013/12/11 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
js常用系统函数用法实例分析
2015/01/12 Javascript
JavaScript中var关键字的使用详解
2015/08/14 Javascript
喜大普奔!jQuery发布 3.0 最终版
2016/06/12 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
AngularJS封装指令方法详解
2016/12/12 Javascript
详解AngularJS中$filter过滤器使用(自定义过滤器)
2017/02/04 Javascript
JS实现容器模块左右拖动效果
2020/01/14 Javascript
全面解析JavaScript Module模式
2020/07/24 Javascript
Python实现LRU算法的2种方法
2015/06/24 Python
mac安装scrapy并创建项目的实例讲解
2018/06/13 Python
Python3.5实现的三级菜单功能示例
2019/03/25 Python
对Python3之方法的覆盖与super函数详解
2019/06/26 Python
html5摇一摇代码优化包括DeviceMotionEvent等等
2014/09/01 HTML / CSS
html2canvas生成的图片偏移不完整的解决方法
2020/05/19 HTML / CSS
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
英国女性时尚品牌:Apricot
2018/12/04 全球购物
美国领先的宠物用品和宠物食品零售商:Petco
2020/10/28 全球购物
2014年小学重阳节活动策划方案
2014/09/16 职场文书
2014年小学安全工作总结
2014/12/04 职场文书
2014年林业工作总结
2014/12/05 职场文书
高中生毕业评语
2014/12/30 职场文书
作弊检讨书
2015/01/27 职场文书
2015年教师节活动总结
2015/03/20 职场文书
公诉意见书范文
2015/06/05 职场文书
Pytorch 如何实现常用正则化
2021/05/27 Python
Oracle 临时表空间SQL语句的实现
2021/09/25 Oracle