函数(2)--闭包

第15条:了解如何在闭包里使用外围作用域中的变量

闭包在 python 中不是很好理解的内容,还是通过简单的例子逐步认识。

1.闭包

如果有一份列表,其中的元素都是数字,现在要对其排序,但排序时,要把出现在某个群组内的数字,放在群组外的那些数字之前。

def sort_priority(values, group):
    def helper(x):
        if x in group:
            return (0, x)
        return (1, x)
    values.sort(key=helper)


numbers = [1, 5, 2, 7, 6, 4, 8, 3, 9]
group = {2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)
>>>
[2, 3, 5, 7, 1, 4, 6, 8, 9]

这里我们使用闭包实现了对列表的排序。之所以这里可以这样去实现,原因如下:

  • Python支持闭包:闭包时一种定义在某个作用域中的函数,这种函数引用了那个作用域里面的变量。
    这里 helper之所以能够访问 group 参数,是因为它是闭包。
  • Python 的函数是一级对象,我们可以直接引用函数,把函数赋给变量或者当成参数传递给其他函数。
    这里把 helper 函数,传给 sort 方法的 key 参数。
  • Python 使用特殊的规则来比较两个元组(也可以比较两个列表)。首先比较各元组中下标为 0 的对应的元素,如果相等,再比较下标为 1 对应的元素,如果还是相等,就比较下标为 2 对应的元素,以此类推。
2.作用域

在表达式中引用变量时,Python 解释器按如下顺序遍历各作用域,
1)当前函数的作用域。
2)任何外围作用域。
3)包含当前代码的外围的作用域。
4)内置作用域。
如果这些地方都没有变量的定义,就会抛出 NameError 异常。

3.获取闭包内的数据

类似于在局部作用域获取全局变量,我们也可以在闭包中修改上一层作用域的变量。在 Python3 中,可以使用 nonlocal 关键字来完成。但是在 Python2 中没有这个关键字,只能使用闭包中使变量未定义的手段来实现到上一层作用域中查找该变量,这还是利用了 python 的作用域遍历顺序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 内置函数续: 35.bytes 函数 bytes 函数返回一个新的 bytes 对象,该对象是一个 0 <= x ...
    一只小釆鸟阅读 3,321评论 0 1
  • 〇、前言 本文共108张图,流量党请慎重! 历时1个半月,我把自己学习Python基础知识的框架详细梳理了一遍。 ...
    Raxxie阅读 19,280评论 17 410
  • 1.必选参数: 必选参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。 2.默认函数: 调用函数时,缺省...
    冬gua阅读 968评论 0 0
  • 局部变量和全局变量局部变量:在一个函数内部定义的变量是局部变量(内部变量),它只在本函数范围内有效,也就是说只有在...
    Eric_Hunter阅读 1,904评论 0 0
  • 今早一醒来就听到窗外滴滴答答的声音,原来是下雨了,幸好昨晚把院子里的东西都收拾了一下。 ...
    羽菲傲霖阅读 994评论 0 0