前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开源图书《Python完全自学教程》7.3.2嵌套函数

开源图书《Python完全自学教程》7.3.2嵌套函数

作者头像
老齐
发布2022-07-06 16:02:28
5200
发布2022-07-06 16:02:28
举报
文章被收录于专栏:老齐教室

7.3.2 嵌套函数

嵌套函数,也是函数作为对象的体现:可以作为函数返回值,即 return 语句中的对象。

代码语言:javascript
复制
>>> def out():
...     def inner():
...         print("this is inner.")
...     print("this is out.")
...     return inner
...

这里定义了两个函数:out()inner() 。只不过这两个函数不是并列关系,而是函数 inner() 在函数 out() 里面,像这样的称为嵌套函数

代码语言:javascript
复制
>>> inner()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'inner' is not defined

函数 inner() 没有在当前位置被定义(其原因参阅7.3.3节)。

代码语言:javascript
复制
>>> out()
this is out.
<function out.<locals>.inner at 0x7fe70f9430d0>

执行了 out() 函数之后,将其内部定义的函数对象作为返回值返回到当前位置。跟其他函数返回值一样,也可以用一个变量引用返回的函数对象 inner

代码语言:javascript
复制
>>> f = out()
this is out.
>>> f
<function out.<locals>.inner at 0x7fe70f9431f0>
>>> f()
this is inner.

变量 f 引用了函数对象 inner ,通过 f() 就可以调用(或执行)该对象,这样被定义在函数 out() 内部的 inner() 就能在当前位置执行了。

嵌套函数除了能说明函数是对象之外,还有别的什么用途吗?

有一类函数,能够产生其他函数,我们形象地称之为“工厂函数”(factory functions)。显然,嵌套函数就是工厂函数。

代码语言:javascript
复制
#coding:utf-8
'''
filename: nestfunc.py
'''

def power_generator(num):
    def power_n(power):
        return num ** power
    return power_n

if __name__ == "__main__":
    power_two = power_generator(2)    # (4)
    power_three = power_generator(3)  # (5)
    print(power_two(8))               # (6)
    print(power_three(2))

此处定义了一个嵌套函数,函数 power_n() 实现了指数运算,但底数 num 是由外层函数 power_generator() 决定的,通过执行 power_generator() 能够得到计算指定底数的乘方运算函数,例如:

  • 注释(4)生成了以 2为底的函数,即通过函数 power_two() 计算 2^n ,其中 npower_two() 的参数,也就是 power_n() 的参数 power 。如 power_two(8) 计算 2^8power_two(10) 计算 2^{10} 等。
  • 同理,注释(5)生成了以 3 为底的函数,专门用于计算 3^n

当然,纯粹计算指数,别的方法也可行。

如果再深入分析这个工厂函数,还会发现“与众不同”之处。例如注释(4),形参 num 引用了整数 2 ,当该函数执行完毕,num 依然存在,体现在注释(6)的 pwoer_two(8) 中。这是因为嵌套在 power_generator() 内部的函数 power_n() 引用了 num 。用一种形象的方法描述此过程,注释(4)得到了一个包裹——函数对象 power_nnum 是一个封闭在此包裹中的变量,不论包裹被快递送到哪里——比如注释(6),num 都会形影不离(因为被封闭在里面了)。像 num 这样的变量(即参数),称之为自由变量——随着包裹可以自由移动。像 power_n() 这样的类似于包裹的函数,称之为闭包(Closure)。

闭包这个术语是由英国计算机科学家彼得·约翰·兰丁(Peter John Landin)于1964年提出,后来因为在 Scheme 语言中的应用而广为流传。在现代编程语言中,所有将函数作为第一类对象的都可以实现闭包,Python 语言就是典型代表。其他没有将函数作为第一类对象的语言,比如 Java ,若要使用闭包,则需要通过类或者接口。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 7.3.2 嵌套函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档