Python闭包与函数对象
1. Python闭包是什么
在python中有函数闭包的概念,这个概念是什么意思呢,查看Wikipedia的说明如下:
“
In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions. Operationally, a closure is a record storing a function[a] together with an environment:[1] a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or storage location to which the name was bound when the closure was created.[b] A closure—unlike a plain function—allows the function to access those captured variables through the closure's reference to them, even when the function is invoked outside their scope.
” —— 原文链接:https://en.wikipedia.org/wiki/Closure_(computer_programming)
看上去概念很多,下面我们通俗的讲一下
假设我有个求x^n的函数如下
def pow(x, n):
res = 1
for i in range(n):
res *= x
return res
(例1)
在某一段代码里,我总是用到平方和(比如求矩形对角线的时候),那我的代码是
len2d = pow(20,2) + pow(30,2)
这时候我希望第二个参数总是取2,不用重复写
在另一段代码里,我总是用到立方和(比如求正方体对角线的时候),那我的代码又变成
len3d = pow(20,3) + pow(30,3) + pow(40,3)
这个时候我希望第二个参数固定为3
在上面这两种情况里,函数闭包就有了用武之地:
def pown(n):
def pow(x):
res = 1
for i in range(n): # 引用外围函数状态
res *= x
return res
return pow
pow2 = pown(2)
len2d = pow2(20) + pow2(30)
pow3 = pown(3)
len3d = pow3(20) + pow3(30) + pow3(40)
(例2)
从例2我们看到,pown是外围函数,它传入了一个参数n,并且返回了一个内部函数。pow就是python中的闭包函数,它不但有自己的执行逻辑,也能引用到参数n。
这就是闭包函数和普通函数最大的不同,闭包函数除了函数执行体,还“闭包”了外围状态。每个闭包函数实例都能“闭包”各自的状态。
2. 闭包和函数对象
如果要把闭包和c++做个对比,应该类似于c++中的函数对象。函数对象用python来实现的代码如下:
class Pow(object):
def __init__(self, n):
self.n = n
def __call__(self, x):
res = 1
for i in range(self.n): # 引用对象成员
res *= x
return res pow2 = Pow(2)
len2d = pow2(20) + pow2(30) pow3 = Pow(3)
len3d = pow3(20) + pow3(30) + pow3(40)
(例3)
例3的类中定义了特殊方法__call__,因此它的对象能被直接做函数调用,称之为函数对象。由于它是一个对象,因此在初始化的时候可以传入参数进行保存,这点就类似于之前提到的闭包的概念。
从这个类比来看,闭包可以近似的看成是简化的函数对象
关键字:Python, 闭包,函数对象
Python闭包与函数对象的更多相关文章
- Python中的函数对象与闭包
函数在Python中是第一类对象,可以当做参数传递给其他函数,放在数据结构中,以及作为函数的返回结果. 下面的例子为接受另外一个函数作为输入并调用它 #foo.py def callf(func): ...
- python中的函数对象与闭包函数
函数对象 在python中,一切皆对象,函数也是对象 在python语言中,声明或定义一个函数时,使用语句: def func_name(arg1,arg2,...): func_suite 当执行流 ...
- Python进阶07 函数对象
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 秉承着一切皆对象的理念,我们再次回头来看函数(function).函数也是一个对象 ...
- python基础之函数对象,嵌套,名称空间和作用域
函数对象: 函数是第一类对象的含义是函数可以被当作数据处理 函数可用于: def func(): print(‘func’) 1.引用 f = func 把内存地址赋值给f 2.当作参数传给一个函 ...
- python中的函数对象的内存地址是多少
今天和同学讨论一个问题,发现了函数的内存地址和我想象的不一样. 我以为同一个函数,假如给的参数不一样,那么这两个函数的id就不一样. 然后经过实验,发现python为了便于管理函数,所有的函数都放在同 ...
- Python中通过函数对象创建全局变量
先看下面这段代码,显然无法work. 因为代码试图在TestVariableScope()中引用一个没有被定义的变量a.所以必须报错,如下图-1. 不过如果你将第2行代码注释掉.代码就能跑通了,如图- ...
- Python 进阶 之 函数对象
Python的世界里,万物皆对象,函数当然也是: 首先要定义一个函数: def add(a,b): print a+b 其次定义一个字典来引用该函数: dic = {"add":a ...
- python入门之函数对象
目录 函数是第一类对象 1.函数名可以被引用 2.函数名可以当做参数传递 3.函数名可以当做返回值使用 4.函数名可以被当做容器类型的元素 函数是第一类对象 First-Class Object : ...
- python 闭包 Closure 函数作为返回值
一.函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. >>> def lazy_sum(*args): ... def sum(): ... ax = ...
随机推荐
- wpf在异步中给前台赋值
wpf,新建异步方法: Thread newThread = new Thread(new ParameterizedThreadStart(GetResult)); newThread.Start( ...
- [原创]Python入门到简单网站目录扫描器编写(上)
1.字符串,整型,浮点型.区别以及用法 |------字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 可以不严格的说,你可以认为引号包括的,都属于字符串 ...
- Java随机数生产算法
java提供了Math.random()函数,返回一个double类型的随机数,也有util包里的Random类,可以生成double,int,float,long,bytes等随机数. 但有些业务需 ...
- SEO学习之路
一.入门建站篇 1.Wamp集成环境安装 2.Wamp集成环境配置多站点 3.DedeCMS安装及目录结构 4.DedeCMS源码安装 5.DedeCMS官方手册 未完待续...
- Javascript:charCodeAt()方法及示例
js charCodeAt()函数说明 返回一个整数,代表指定位置上字符的 Unicode 编码.该Unicode编码为十六进制 strObj.charCodeAt(index) 参数: strObj ...
- (转)Eclipse/Myeclipse 注释注释模板
Window -->preferences --> Java --> Code Style --> Code Templates --> Comments --> ...
- cocos2dx--cocos2dx3.1.1执行报无法解析的外部符号
使用cocos2dx3.1.1和VS2012 新建了一个名为test的工程.放在D:\cocos2dx\cocos2d-x-3.1.1\projects下 编译通过,没问题 用cocostudio的场 ...
- 数据库(SQLITE3函数总结): sqlite3_open, sqlite3_exec, slite3_close,sqlite3_prepare_v2,sqlite3_column_text,
Sqlite3 的确非常好用.小巧.速度快.近期研究它,有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记. 导入SQLLite library并引入头文件. libsqlite3.dyl ...
- openwrt time sycronize
三行命令搞定这个. opkg update opkg install ntpclient ntpclient -s -c 0 -h ntp.sjtu.edu.cn 最后把这个 放到 rc.local ...
- php图片上面写文字,输出图片
<?php /* param $image 图象资源 param size 字体大小 param angle 字体输出角度 param showX 输出位置x坐标 param showY 输出位 ...