python 您所在的位置:网站首页 js内嵌函数和嵌套函数区别 python

python

2024-05-25 01:55| 来源: 网络整理| 查看: 265

一、概述 Python中,是一切皆对象的,函数当然也是,因此函数内部是可以再嵌套函数的,这一点下面可以举例子说明。 再延伸一点,就能引申出一个高级概念了:[闭包](http://baike.baidu.com/link?url=rrHziqwEvt5X-2w76dqfp47N1pG7H8wKEKdXLmiLqbN0WXgFeXKfM8pPJNzuIBEsju-aNris6NK0vI6IH_hx2ci1OaqZ8hYYPhrySwmBof_)。嵌套函数在其外部函数(但不是全局区域)内使用,那么这个嵌套函数就会被认为是闭包。 如前所述,闭包是一个高级概念,一般在函数式编程(一种编程范式,与面向对象编程和面向过程编程是同级别的)中提到的比较多。Python也可以实现函数式编程。本文采用的是python3.5。 二、内嵌函数 先举个例子吧: def func1(x): def func2(y): return x*y return func2 print(func1(3)(4))

如上例子所示,func2就是定义在func1中的函数,所以他是一个内嵌函数,在func1返回的时候是直接返回的函数名的,为什么可以这样呢?因为在函数式编程中,认为函数本身就是一个对象,我们现在不过是将对象返回了而已,当然可以做到。

为方便起见,如果定义两个入参为空的函数,如下所示:

def func1(): x=6 def func2(): x *= x return x return func2 print(func1()())

系统就会报错:

Traceback (most recent call last): File "", line 8, in print(func1()()) File "", line 4, in func2 x *= x UnboundLocalError: local variable 'x' referenced before assignment

其实,在python的函数中和全局同名的变量,如果你有修改变量的值就会变成局部变量,在修改之前对该变量的引用自然就会出现没定义这样的错误了,如果确定要引用全局变量,并且要对它修改,就有两种方式了: (1).加上global关键字; (2).使用nonlocal关键字。 在此,试下nonlocal的方法:

def func1(): x=6 def func2(): nonlocal x #global x x *= x return x return func2 print(func1())

输出为36

同样有一个疑问,如果在python2中,怎么办?Python2可是没有这些关键字的。怎么办?来分析一下: 之所以会报上述错误,还是因为程序都是默认存储在stack中的,函数结束后,内存就会释放,因此无法访问到。所以要想能访问到,必须换一个存储的地方,比如list。,那就有了修改的方法了,如下所示:

def func1(): x=[6] def func2(): x[0] *= x[0] return x[0] return func2 print(func1()())

或许Python热爱者觉得这种方法有些不太”正大光明”,因此才在python3中引入nonlocal这个了不起的关键字吧。

三、闭包

如二可知,一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。在Python中,所谓的闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的closure属性中。比如下面的代码:

print(func1().__closure__) 输出:None

下面再看一个闭包提高代码可复用性的例子:

def line_conf(a, b): def line(x): return a*x + b return line line1 = line_conf(1, 1) line2 = line_conf(4, 5) print(line1(5), line2(5))

这个例子中,函数line与环境变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个环境变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。

如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。利用闭包,我们实际上创建了泛函。line函数定义一种广泛意义的函数。这个函数的一些方面已经确定(必须是直线),但另一些方面(比如a和b参数待定)。随后,我们根据line_conf传递来的参数,通过闭包的形式,将最终函数确定下来。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有