python-内嵌函数和闭包
来源:互联网 发布:魔域名剑客之墓攻略 编辑:程序博客网 时间:2024/06/06 08:25
一、概述
Python中,是一切皆对象的,函数当然也是,因此函数内部是可以再嵌套函数的,这一点下面可以举例子说明。再延伸一点,就能引申出一个高级概念了:[闭包](http://baike.baidu.com/link?url=rrHziqwEvt5X-2w76dqfp47N1pG7H8wKEKdXLmiLqbN0WXgFeXKfM8pPJNzuIBEsju-aNris6NK0vI6IH_hx2ci1OaqZ8hYYPhrySwmBof_)。嵌套函数在其外部函数(但不是全局区域)内使用,那么这个嵌套函数就会被认为是闭包。如前所述,闭包是一个高级概念,一般在函数式编程(一种编程范式,与面向对象编程和面向过程编程是同级别的)中提到的比较多。Python也可以实现函数式编程。本文采用的是python3.5。
二、内嵌函数
先举个例子吧:
def func1(x): def func2(y): return x*y return func2print(func1(3)(4))
如上例子所示,func2就是定义在func1中的函数,所以他是一个内嵌函数,在func1返回的时候是直接返回的函数名的,为什么可以这样呢?因为在函数式编程中,认为函数本身就是一个对象,我们现在不过是将对象返回了而已,当然可以做到。
为方便起见,如果定义两个入参为空的函数,如下所示:
def func1(): x=6 def func2(): x *= x return x return func2print(func1()())
系统就会报错:
Traceback (most recent call last): File "<ipython-input-9-60edb29d8b8d>", line 8, in <module> print(func1()()) File "<ipython-input-9-60edb29d8b8d>", line 4, in func2 x *= xUnboundLocalError: 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 func2print(func1())
输出为36
同样有一个疑问,如果在python2中,怎么办?Python2可是没有这些关键字的。怎么办?来分析一下:
之所以会报上述错误,还是因为程序都是默认存储在stack中的,函数结束后,内存就会释放,因此无法访问到。所以要想能访问到,必须换一个存储的地方,比如list。,那就有了修改的方法了,如下所示:
def func1(): x=[6] def func2(): x[0] *= x[0] return x[0] return func2print(func1()())
或许Python热爱者觉得这种方法有些不太”正大光明”,因此才在python3中引入nonlocal这个了不起的关键字吧。
三、闭包
如二可知,一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。在Python中,所谓的闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的closure属性中。比如下面的代码:
print(func1().__closure__)输出:None
下面再看一个闭包提高代码可复用性的例子:
def line_conf(a, b): def line(x): return a*x + b return lineline1 = 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传递来的参数,通过闭包的形式,将最终函数确定下来。
- python-内嵌函数和闭包
- Python-16 函数:内嵌函数和闭包
- python基础学习之函数(2)-内嵌函数和闭包
- Python:函数3——内嵌函数和闭包
- 内嵌函数和闭包
- 内嵌函数和闭包
- 零基础入门学习Python(11):内嵌函数、闭包和变量作用域
- 【Python基础】--字符串str/序列/全局标志位/全局变量/内嵌函数和闭包
- Python -- 内嵌函数 & closure(闭包) 浅析
- 020:函数:内嵌函数和闭包
- Js内嵌函数与闭包
- FishC笔记—20 讲 函数:内嵌函数和闭包
- Python函数闭包和语法糖
- Python函数作用域和闭包
- python闭包函数和装饰器
- Python闭包函数和一些BIF
- python学习笔记(三) 实现switch,内建函数,模块和包
- Python工厂函数和内建函数
- 第一个博客:简单的工厂
- go语言开发工具Gogland
- Servlet(18)ServletContext
- 第十五届北京师范大学程序设计竞赛决赛 A.Another Server【思维】
- NG的ML课程week3编程问题
- python-内嵌函数和闭包
- getClassLoader().getResourceAsStream
- 第一个面向对象程序——日期类
- OCR识别驾驶证识别私有云
- 马云马化腾崇拜的硅谷大神:这十二个趋势是未来致富之路(上)
- PHP 开发者该知道的 5 个 Composer 小技巧
- YOLOv2 论文笔记
- 将二叉树拆成链表
- [LeetCode]290. Word Pattern