学习python的第21天

一.python闭包

1.定义

闭包,又称闭包函数或者闭合函数,其实和前面讲的嵌套函数类似,不同之处在于,闭包中外部函数返回的
不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继
续执行调用。

例如,计算一个数的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)

很显然,第二种表达方式更为简洁易读,每次都可以少输参数

其次,和缩减嵌套函数的优点类似,函数开头需要做一些额外工作,当需要多次调用该函数时,如果将那些
额外工作的代码放在外部函数,就可以减少多次调用导致的不必要开销,提高程序的运行效率。 

2.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__ 属性的类型是一个元组,这表明闭包可以支持多个自由变量的形式。

 二.lambda表达式(匿名函数)

lambda 表达式,又称匿名函数,常用来表示内部仅包含 1 行表达式的函数。如果一个函数的函数体
仅有1行表达式,则该函数就可以用 lambda 表达式来代替。

语法格式如下:

name = lambda [list] : 表达式
其中,定义 lambda 表达式,必须使用 lambda 关键字;[list] 作为可选参数,等同于定义函数是指定的参数列表;value 为该表达式的名称。

转换为普通函数

    def name(list):
        return 表达式
    name(list)

倘若我们设计一个计算两数之和的函数,普通函数如下

    def add(x, y):
        return x+ y
    print(add(3,4))

又因为上面的函数仅有一行表达式,因此可用lambda表达式

    add = lambda x,y:x+y
    print(add(3,4))
可以这样理解 lambda 表达式,其就是简单函数(函数体仅是单行的表达式)的简写版本。相比函数,
lamba 表达式具有以下  2 个优势:

对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁;
对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高程序执行的性能。(很重要)
​

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值