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爬取APP下载链接的实现方法
Sep 30 Python
Python之自动获取公网IP的实例讲解
Oct 01 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
May 30 Python
python 列表递归求和、计数、求最大元素的实例
Nov 28 Python
Empty test suite.(PyCharm程序运行错误的解决方法)
Nov 30 Python
Django 1.10以上版本 url 配置注意事项详解
Aug 05 Python
python django生成迁移文件的实例
Aug 31 Python
使用PyCharm进行远程开发和调试的实现
Nov 04 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
Python作用域与名字空间原理详解
Mar 21 Python
Python数据相关系数矩阵和热力图轻松实现教程
Jun 16 Python
浅析PyCharm 的初始设置(知道)
Oct 12 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
用libtemplate实现静态网页生成
2006/10/09 PHP
php实现监听事件
2013/11/06 PHP
简单谈谈php中ob_flush和flush的区别
2014/11/27 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
2016/09/26 PHP
基于Jquery的将DropDownlist的选中值赋给label的实现代码
2011/05/06 Javascript
JavaScript函数的4种调用方法详解
2014/04/22 Javascript
JavaScript基本语法学习教程
2016/01/14 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
三种带箭头提示框总结实例
2016/06/14 Javascript
微信小程序 Record API详解及实例代码
2016/09/30 Javascript
jQuery扩展实现text提示还能输入多少字节的方法
2016/11/28 Javascript
Node.js使用gm拼装sprite图片
2017/07/04 Javascript
Bootstrap 按钮样式与使用代码详解
2018/12/09 Javascript
Vue infinite update loop的问题解决
2019/04/23 Javascript
JavaScript动态检测密码强度原理及实现方法详解
2019/06/11 Javascript
微信小程序 如何保持登录状态
2019/08/16 Javascript
如何使用webpack打包一个库library的方法步骤
2019/12/18 Javascript
[01:44]Ti10举办地公布
2019/08/25 DOTA
python 字典中取值的两种方法小结
2018/08/02 Python
python内存管理机制原理详解
2019/08/12 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
德国低价购买灯具和家具网站:Style-home.de
2016/11/25 全球购物
PHP中如何使用Cookie
2015/10/28 面试题
金士达面试非笔试
2012/03/14 面试题
UNIX操作系统结构由哪几部分组成
2016/02/17 面试题
领导的自我鉴定
2013/12/28 职场文书
大学毕业感言
2014/01/10 职场文书
幼儿园教师教育感言
2014/02/28 职场文书
党性观念心得体会
2014/09/03 职场文书
大一学生个人总结
2015/02/15 职场文书
2015年七一建党节慰问信
2015/03/23 职场文书
小学中队委竞选稿
2015/11/20 职场文书
oracle重置序列从0开始递增1
2022/02/28 Oracle
Python实现视频自动打码的示例代码
2022/04/08 Python
Python使用Opencv打开笔记本电脑摄像头报错解问题及解决
2022/06/21 Python
HTML实现仿Windows桌面主题特效的实现
2022/06/28 HTML / CSS