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使用scrapy采集数据过程中放回下载过大页面的方法
Apr 08 Python
举例讲解Python的Tornado框架实现数据可视化的教程
May 02 Python
matplotlib作图添加表格实例代码
Jan 23 Python
python监控文件并且发送告警邮件
Jun 21 Python
python实现嵌套列表平铺的两种方法
Nov 08 Python
python如何获取当前文件夹下所有文件名详解
Jan 25 Python
python调用matplotlib模块绘制柱状图
Oct 18 Python
OpenCV 表盘指针自动读数的示例代码
Apr 10 Python
python 实现仿微信聊天时间格式化显示的代码
Apr 17 Python
使用darknet框架的imagenet数据分类预训练操作
Jul 07 Python
详解Python中openpyxl模块基本用法
Feb 23 Python
python中pandas.read_csv()函数的深入讲解
Mar 29 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如何统计Nginx日志的User Agent数据
2019/03/06 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
prototype.js的Ajax对象
2006/09/23 Javascript
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
jQuery基本过滤选择器使用介绍
2013/04/18 Javascript
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
2013/05/13 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
创建一般js对象的几种方式
2017/01/19 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
2017/03/13 Javascript
基于jQuery实现的单行公告活动轮播效果
2017/08/23 jQuery
js实现鼠标跟随运动效果
2020/08/02 Javascript
AngularJS集合数据遍历显示的实例
2017/12/27 Javascript
JS实现统计字符串中字符出现个数及最大个数功能示例
2018/06/04 Javascript
JS高阶函数原理与用法实例分析
2019/01/15 Javascript
如何利用vue+vue-router+elementUI实现简易通讯录
2019/05/13 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
2020/04/11 Javascript
从0搭建vue-cli4脚手架
2020/06/17 Javascript
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
详解django的serializer序列化model几种方法
2018/10/16 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
wxPython实现绘图小例子
2019/11/19 Python
django实现日志按日期分割
2020/05/21 Python
CSS3 中的@keyframes介绍
2014/09/02 HTML / CSS
css和css3弹性盒模型实现元素宽度(高度)自适应
2019/05/15 HTML / CSS
html5新增的属性和废除的属性简要概述
2013/02/20 HTML / CSS
HTML5离线应用与客户端存储的实现
2018/05/03 HTML / CSS
德国高尔夫商店:Par71.de
2020/11/29 全球购物
财务主管自我鉴定
2014/01/17 职场文书
八项规定整改方案
2014/02/21 职场文书
民主评议政风行风整改方案
2014/09/17 职场文书
购房委托书范本
2014/09/18 职场文书
电影复兴之路观后感
2015/06/02 职场文书
小学庆六一主持词
2015/06/30 职场文书
微信告警的zabbix监控系统 监控整个NGINX集群
2022/04/18 Servers