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中执行shell的两种方法总结
Jan 10 Python
Python中模块pymysql查询结果后如何获取字段列表
Jun 05 Python
Python编程之string相关操作实例详解
Jul 22 Python
python实现桌面气泡提示功能
Jul 29 Python
Python定时任务随机时间执行的实现方法
Aug 14 Python
pygame实现贪吃蛇游戏(下)
Oct 29 Python
Jupyter Notebook 实现正常显示中文和负号
Apr 24 Python
python redis存入字典序列化存储教程
Jul 16 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
Oct 16 Python
pymysql模块使用简介与示例
Nov 17 Python
基于Python的图像阈值化分割(迭代法)
Nov 20 Python
分享python函数常见关键字
Apr 26 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
WebQQ最新登陆协议的用法
2014/12/22 PHP
全面解读PHP的Yii框架中的日志功能
2016/03/17 PHP
PHP性能测试工具xhprof安装与使用方法详解
2018/04/29 PHP
使用js实现一个可编辑的select下拉列表
2014/02/20 Javascript
Windows系统下Node.js的简单入门教程
2015/06/23 Javascript
基于jQuery实现动态数字展示效果
2015/08/12 Javascript
jQuery实现form表单基于ajax无刷新提交方法详解
2015/12/08 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
禁用backspace网页回退功能的实现代码
2016/11/15 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(放大缩小)
2016/12/02 Javascript
微信小程序 picker-view 组件详解及简单实例
2017/01/10 Javascript
AngularJS的ng-repeat指令与scope继承关系实例详解
2017/01/21 Javascript
详解vue-loader在项目中是如何配置的
2018/06/04 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
vue全屏事件开发详解
2020/06/17 Javascript
vue监听滚动事件的方法
2020/12/21 Vue.js
js实现随机点名功能
2020/12/23 Javascript
[02:05]DOTA2完美大师赛趣味视频之看我表演
2017/11/18 DOTA
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
2017/09/08 Python
python中format()函数的简单使用教程
2018/03/14 Python
python操作mysql代码总结
2018/06/01 Python
Python 实现Windows开机运行某软件的方法
2018/10/14 Python
Python中的 enum 模块源码详析
2019/01/09 Python
python实现得到当前登录用户信息的方法
2019/06/21 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
js实现移动端H5页面手指滑动刻度尺功能
2017/11/16 HTML / CSS
阿迪达斯比利时官方商城:adidas比利时
2016/10/10 全球购物
大四学生毕业自荐信
2013/11/07 职场文书
好军嫂事迹材料
2014/01/15 职场文书
司马光教学反思
2014/02/01 职场文书
英文求职信写作小建议
2014/02/16 职场文书
初中语文教学反思范文
2016/03/03 职场文书
浅谈MySQL之select优化方案
2021/08/07 MySQL
MySQL sql模式设置引起的问题
2022/05/15 MySQL
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL