美文网首页
python-闭包

python-闭包

作者: 阳光小镇少爷 | 来源:发表于2023-04-09 10:24 被阅读0次

闭包就是外部函数中定义一个内部函数,内部函数引用外部函数中的变量,外部函数的返回值是内部函数;

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境) 在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures), 是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。 所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。

闭包的特征
特征:
1.嵌套函数
2.内层函数引用了外层函数的变量
3.内层函数作为返回值返回给外层函数

特征2:
自由变量: 既不是局部变量,也不是模块全局变量;在闭包的时候:内层引用外层函数的变量
保存我们要执行代码的环境
执行的代码块和为自由变量提供绑定的计算环境两者的结合

例如,计算一个数的 n 次幂,用闭包可以写成下面的代码:

闭包函数,其中 exponent 称为自由变量

def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of # 返回值是 exponent_of 函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方
print(square(2)) # 计算 2 的平方
print(cube(2)) # 计算 2 的立方
运行结果为:
4
8

在上面程序中,外部函数 nth_power() 的返回值是函数 exponent_of(),而不是一个具体的数值。

需要注意的是,在执行完 square = nth_power(2) 和 cube = nth_power(3) 后,外部函数 nth_power() 的参数 exponent 会和内部函数 exponent_of 一起赋值给 squre 和 cube,这样在之后调用 square(2) 或者 cube(2) 时,程序就能顺利地输出结果,而不会报错说参数 exponent 没有定义。

看到这里,读者可能会问,为什么要闭包呢?上面的程序,完全可以写成下面的形式:
def nth_power_rewrite(base, exponent):
return base ** exponent
上面程序确实可以实现相同的功能,不过使用闭包,可以让程序变得更简洁易读。设想一下,比如需要计算很多个数的平方,那么读者觉得写成下面哪一种形式更好呢?

不使用闭包

res1 = nth_power_rewrite(base1, 2)
res2 = nth_power_rewrite(base2, 2)
res3 = nth_power_rewrite(base3, 2)

使用闭包

square = nth_power(2)
res1 = square(base1)
res2 = square(base2)
res3 = square(base3)
显然第二种方式表达更为简洁,在每次调用函数时,都可以少输入一个参数。

其次,和缩减嵌套函数的优点类似,函数开头需要做一些额外工作,当需要多次调用该函数时,如果将那些额外工作的代码放在外部函数,就可以减少多次调用导致的不必要开销,提高程序的运行效率。
Python闭包的closure属性
闭包比普通的函数多了一个 closure 属性,该属性记录着自由变量的地址。当闭包被调用时,系统就会根据该地址找到对应的自由变量,完成整体的函数调用。

以 nth_power() 为例,当其被调用时,可以通过 closure 属性获取自由变量(也就是程序中的 exponent 参数)存储的地址,例如:
def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of
square = nth_power(2)

查看 closure 的值

print(square.closure)
输出结果为:
(<cell at 0x0000014454DFA948: int object at 0x00000000513CC6D0>,)

可以看到,显示的内容是一个 int 整数类型,这就是 square 中自由变量 exponent 的初始值。还可以看到,closure 属性的类型是一个元组,这表明闭包可以支持多个自由变量的形式。

相关文章

  • python-闭包

    函数里面的函数不被执行,返回了内部函数的引用。 ret(200), # 300传当前的值,可以计算 闭包的应用 如...

  • Python-闭包

    0. 函数相关知识 1)Python中“一切皆对象”,函数也不例外 先定义一个函数: def func(): p...

  • Python-闭包

    闭包的理解 我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值...

  • Python-闭包

    当函数调用完,函数内定义的,但是我们有时候需要,每次在这个变量的基础上完成一系列操作,比如:每次在这个变量的基础上...

  • python-闭包和装饰器

    https://www.zhihu.com/question/25950466/answer/31731502 代...

  • Python-闭包和修饰器

    作用域 闭包 code: 装饰器 code: 装饰器案例 code:

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

网友评论

      本文标题:python-闭包

      本文链接:https://www.haomeiwen.com/subject/xecuddtx.html