首页 技术 正文
技术 2022年11月14日
0 收藏 610 点赞 3,663 浏览 1671 个字

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 respow2 = Pow(2)
len2d = pow2(20) + pow2(30)pow3 = Pow(3)
len3d = pow3(20) + pow3(30) + pow3(40)

(例3)

例3的类中定义了特殊方法__call__,因此它的对象能被直接做函数调用,称之为函数对象。由于它是一个对象,因此在初始化的时候可以传入参数进行保存,这点就类似于之前提到的闭包的概念。

从这个类比来看,闭包可以近似的看成是简化的函数对象

关键字:Python, 闭包,函数对象

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,145
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,617
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,461
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,236
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,871
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,952