Python、Javascript中的闭包比较

yipeiwu_com5年前Python基础

同为脚本语言,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变量声明,变量作用域的相似和不同之处。

相关文章

Django实现分页显示效果

Django中提供了一个类Paginator专门用来管理和处理分页数据,所以我们在使用之前先导入好相应的类,,另外这里我们也导入了待会会用到的处理异常的两个类 EmptyPage和Pag...

10招!看骨灰级Pythoner玩转Python的方法

10招!看骨灰级Pythoner玩转Python的方法

pandas是基于numpy构建的,使数据分析工作变得更快更简单的高级数据结构和操作工具。本文为大家带来10个玩转Python的小技巧,学会了分分钟通关变大神! 1. read_cs...

使用 tf.nn.dynamic_rnn 展开时间维度方式

使用 tf.nn.dynamic_rnn 展开时间维度方式

对于单个的 RNNCell , 使用色的 call 函数进行运算时 ,只是在序列时间上前进了一步 。如使用 x1、 ho 得到此h1, 通过 x2 、 h1 得到 h2 ...

python方法生成txt标签文件的实例代码

python方法生成txt标签文件的实例代码

1、如果想要利用代码(不论是python、c++、亦或是matlab)实现生成标签文件,首先,也是灰常重要的一件事就是你的图片集一定要是有规律的命名。数字字母顺序排开。这一点非常重要,相...

Python中矩阵库Numpy基本操作详解

NumPy是一个关于矩阵运算的库,熟悉Matlab的都应该清楚,这个库就是让python能够进行矩阵话的操作,而不用去写循环操作。 下面对numpy中的操作进行总结。 numpy包含...