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多进程编程下线程之间变量的共享问题
May 05 Python
利用python解决mysql视图导入导出依赖的问题
Dec 17 Python
python实现redis三种cas事务操作
Dec 19 Python
python中ASCII码字符与int之间的转换方法
Jul 09 Python
python批量复制图片到另一个文件夹
Sep 17 Python
python单线程下实现多个socket并发过程详解
Jul 27 Python
Python:合并两个numpy矩阵的实现
Dec 02 Python
python opencv如何实现图片绘制
Jan 19 Python
Python3 shutil(高级文件操作模块)实例用法总结
Feb 19 Python
tensorflow实现从.ckpt文件中读取任意变量
May 26 Python
Docker如何部署Python项目的实现详解
Oct 26 Python
Python中快速掌握Data Frame的常用操作
Mar 31 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常用代码
2006/11/23 PHP
PHP实现下载功能的代码
2012/09/29 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
一段实时更新的时间代码
2006/07/07 Javascript
使用iframe window的scroll方法控制iframe页面滚动
2014/03/05 Javascript
javascript闭包入门示例
2014/04/30 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
2016/01/18 Javascript
Web开发必知Javascript技巧大全
2016/02/23 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
微信小程序利用co处理异步流程的方法教程
2017/05/20 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
JQuery 实现文件下载的常用方法分析
2019/10/29 jQuery
微信小程序登陆注册功能的实现代码
2019/12/10 Javascript
Vue的v-model的几种修饰符.lazy,.number和.trim的用法说明
2020/08/05 Javascript
python模拟登陆阿里妈妈生成商品推广链接
2014/04/03 Python
深入解析Python中的descriptor描述器的作用及用法
2016/06/27 Python
Python递归函数定义与用法示例
2017/06/02 Python
python3.6编写的单元测试示例
2019/08/17 Python
python thrift 实现 单端口多服务的过程
2020/06/08 Python
Python自省及反射原理实例详解
2020/07/06 Python
python3环境搭建过程(利用Anaconda+pycharm)完整版
2020/08/19 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
浅析python连接数据库的重要事项
2021/02/22 Python
美国最大的宠物药店:1-800-PetMeds
2016/10/02 全球购物
小天鹅官方商城:LittleSwan
2017/06/16 全球购物
瑜伽国际:Yoga International
2018/04/18 全球购物
Ego Shoes官网:英国时髦鞋类品牌
2020/10/19 全球购物
中层干部岗位职责
2013/12/18 职场文书
执行总经理岗位职责
2014/02/03 职场文书
大学毕业自我鉴定范文
2014/02/03 职场文书
对公司合理化的建议书
2014/03/12 职场文书
追悼会答谢词
2015/01/05 职场文书
辞职报告(范文三篇)
2019/08/27 职场文书
golang中的空slice案例
2021/04/27 Golang