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入门及进阶笔记 Python 内置函数小结
Aug 09 Python
Python中join和split用法实例
Apr 14 Python
window下eclipse安装python插件教程
Apr 24 Python
Request的中断和ErrorHandler实例解析
Feb 12 Python
python抓取文件夹的所有文件
Feb 27 Python
对Python3中的print函数以及与python2的对比分析
May 02 Python
python3.6使用pymysql连接Mysql数据库
May 25 Python
Python中那些 Pythonic的写法详解
Jul 02 Python
在linux下实现 python 监控usb设备信号
Jul 03 Python
django 信号调度机制详解
Jul 19 Python
python 爬虫如何正确的使用cookie
Oct 27 Python
如何使用pdb进行Python调试
Jun 30 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
解析thinkphp中的导入文件标签
2013/06/20 PHP
PHP实现的英文名字全拼随机排号脚本
2014/07/04 PHP
php正则preg_replace_callback函数用法实例
2015/06/01 PHP
php获取远程文件的内容和大小
2015/11/03 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
关于JavaScript中的关联数组分析
2013/04/09 Javascript
JS实现单行文字不间断向上滚动的方法
2015/01/29 Javascript
jQuery实现鼠标划过展示大图的方法
2015/03/09 Javascript
js验证上传图片的方法
2015/05/12 Javascript
javascript实现给定半径求出圆的面积
2015/06/26 Javascript
JavaScript 七大技巧(二)
2015/12/13 Javascript
获取阴历(农历)和当前日期的js代码
2016/02/15 Javascript
使用pcs api往免费的百度网盘上传下载文件的方法
2016/03/17 Javascript
JS识别浏览器类型(电脑浏览器和手机浏览器)
2016/11/18 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
Vue自定义指令封装节流函数的方法示例
2018/07/09 Javascript
vueScroll实现移动端下拉刷新、上拉加载
2019/03/22 Javascript
Vue.js构建你的第一个包并在NPM上发布的方法步骤
2019/05/01 Javascript
Vue项目中ESlint规范示例代码
2019/07/04 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
2020/03/26 Javascript
Angular利用HTTP POST下载流文件的步骤记录
2020/07/26 Javascript
python使用PyGame播放Midi和Mp3文件的方法
2015/04/24 Python
python搜索指定目录的方法
2015/04/29 Python
python 简单的绘图工具turtle使用详解
2017/06/21 Python
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
python导入模块交叉引用的方法
2019/01/19 Python
python3利用Socket实现通信的方法示例
2019/05/06 Python
pytorch方法测试详解——归一化(BatchNorm2d)
2020/01/15 Python
企业门卫岗位职责
2013/12/12 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
《长相思》听课反思
2014/04/10 职场文书
活动总结的格式
2014/05/07 职场文书
办公室主任四风问题对照检查材料思想汇报
2014/09/28 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
车辆管理制度范本
2015/08/05 职场文书
治庸问责工作总结
2015/08/11 职场文书