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入门教程之运算符与控制流
Aug 17 Python
使用Python实现简单的服务器功能
Aug 25 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
Jun 11 Python
Python3.5 Json与pickle实现数据序列化与反序列化操作示例
Apr 29 Python
Python中函数参数匹配模型详解
Jun 09 Python
用Python配平化学方程式的方法
Jul 20 Python
python文档字符串(函数使用说明)使用详解
Jul 30 Python
使用pycharm和pylint检查python代码规范操作
Jun 09 Python
python多线程semaphore实现线程数控制的示例
Aug 10 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
python ansible自动化运维工具执行流程
Jun 24 Python
进行数据处理的6个 Python 代码块分享
Apr 06 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的日期处理函数及uchome的function_coomon中日期处理函数的研究
2011/01/12 PHP
PHP下判断网址是否有效的代码
2011/10/08 PHP
php+ajax实现无刷新动态加载数据技术
2015/04/28 PHP
php实现微信支付之现金红包
2018/05/30 PHP
html数组字符串拼接的最快方法
2009/09/16 Javascript
一个报数游戏js版(约瑟夫环问题)
2010/08/05 Javascript
JavaScript 模式之工厂模式(Factory)应用介绍
2012/11/15 Javascript
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
2013/04/28 Javascript
window.showModalDialog参数传递中含有特殊字符的处理方法
2013/06/06 Javascript
JS控制阿拉伯数字转为中文大写示例代码
2013/09/04 Javascript
优化javascript的执行效率一些方法总结
2013/12/25 Javascript
JS对象转换为Jquery对象示例
2014/01/26 Javascript
node.js中的http.request.end方法使用说明
2014/12/10 Javascript
详解WordPress开发中get_current_screen()函数的使用
2016/01/11 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
JavaScript中的对象和原型(一)
2016/08/12 Javascript
AngularJS 作用域详解及示例代码
2016/08/17 Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
2016/10/28 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
bootstrap使用validate实现简单校验功能
2016/12/02 Javascript
prototype与__proto__区别详细介绍
2017/01/09 Javascript
JS动态插入脚本和插入引用外部链接脚本的方法
2018/05/21 Javascript
Python 使用 attrs 和 cattrs 实现面向对象编程的实践
2019/06/12 Python
Python 变量的创建过程详解
2019/09/02 Python
下载与当前Chrome对应的chromedriver.exe(用于python+selenium)
2020/01/14 Python
美国奢侈品在线团购网站:Gilt City
2017/11/16 全球购物
美国电子产品购物网站:BuyDig.com
2020/06/17 全球购物
工作时间上网检讨书
2014/02/03 职场文书
园艺师求职信
2014/03/10 职场文书
团日活动总结怎么写
2014/06/25 职场文书
就业协议书范本
2014/10/08 职场文书
教师工作总结范文2014
2014/11/10 职场文书
消防验收申请报告
2015/05/15 职场文书
校运会班级霸气口号
2015/12/24 职场文书
技术转让协议书
2016/03/19 职场文书
Nginx图片服务器配置之后图片访问404的问题解决
2022/03/21 Servers