![Python 3.7从入门到精通(视频教学版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/212/31476212/b_31476212.jpg)
6.8 返回函数
在Python语言中,函数不仅可以作为其他函数的参数,还可以作为其他函数的返回结果。
下面通过示例来学习返回函数的用法。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P135_57428.jpg?sign=1739329929-cRxhVdlw1bAyaFd2Bjap5fzlz7xRrF5p-0-56b0925349b785825c3872ad83dc9d29)
运行结果如图6-34所示。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P135_13135.jpg?sign=1739329929-qzlPvhCFEeUhqLh6tT0r4ZkzlleRjCkn-0-8f9c216c09a3f0f6b0683093b94ff8f0)
图6-34 运行结果
从运行结果可以看出,直接调用f1()函数时,没有返回求绝对值的结果,而是返回了一串字符(这个字符其实就是函数)。当执行m()函数时,才真正计算绝对值的结果。
在上述示例中,函数f1()又定义了一个f2()函数,并且内部函数f2()可以引用外部函数f1()的参数。当函数f1()返回函数f2()时,相关参数都保存在返回函数中,称为闭包。
注意 当调用f1()函数时,每次调用都会返回一个新的函数,即使传入相同的参数也是如此。例如:
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P136_57429.jpg?sign=1739329929-2xbbnnC3sSEZt2vWRZBpEA7W41y4vsyM-0-50c345e19f638cd38b8145cac36e9a14)
运行结果如图6-35所示。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P136_13173.jpg?sign=1739329929-46iCy9ptKANCQkYiLBcxjb7cEOfocpfm-0-a5dc09eae65e5908900ee013a8a4e61a)
图6-35 运行结果
从运行结果可以看出,返回的函数m1和m2不同。
如果在一个内部函数里对外部作用域(不是全局作用域)的变量进行引用,内部函数就称为闭包。
例如:
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P136_57430.jpg?sign=1739329929-t0XivcNuTQ4LJodCHfsQvgsMZL40DSBg-0-3ffd0a9ae81ee05c46d3a74e2073e2dd)
运行结果如图6-36所示。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P136_13227.jpg?sign=1739329929-6oTkBOvypoSQxunSjne7UxolJ3Gv6I4F-0-8a8f607a64bc1f41cd96149c6f39bb9f)
图6-36 运行结果
地上述示例中,函数f2对函数f1的参数n进行了引用,将带参数的函数f1给一个新的函数p1。当函数f1的生命周期结束时,已经引用的变量n存放在函数f2中,依然可以调用。
【例6.5】闭包中引用循环参数(源代码\ch06\6.5.py)。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P137_57431.jpg?sign=1739329929-suVZa4pE5erIiSswPWHHd0O9aL87GDRE-0-27f9253f9c02f3b4b0b1283dbf1d05d9)
在本示例中,每次循环都创建一个新函数,最后把3个函数都返回了。那么执行该函数得到的结果是什么?
保存并运行程序,结果如图6-37所示。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P137_13324.jpg?sign=1739329929-l7Iw4WgjQ20ButNP9dx6Vsoy9QWZb06k-0-ba7103ba7e247146c79f1444ef4098b6)
图6-37 运行结果
从运行结果可以看出,3个函数返回的结果均为9。此时读者可能会有疑问,为什么调用函数f1()、f2()和f3()的结果不是1、4和9呢?
出现上述结果的原因是返回的函数引用了变量i,但并非立刻执行,等到三个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果均为9。
注意 尽量避免在闭包中引用循环变量,或者后续会发生变化的变量,否则会出现意外情况。
如果一定需要引用循环变量,那么可以增加一个函数,并且使用该函数的参数绑定循环变量当前的值。
例如将上面的示例修改如下:
【例6.6】闭包中引用循环变量,绑定循环变量当前的值(源代码\ch06\6.6.py)。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P137_57432.jpg?sign=1739329929-yPrJB5HeouD69ZaYtETA0b9u3KBLU9cV-0-0b666fbed4c1abc10cb90e57ee190c25)
保存并运行程序,结果如图6-38所示。
![](https://epubservercos.yuewen.com/5D8A8A/17035792904285406/epubprivate/OEBPS/Images/Figure-P138_13427.jpg?sign=1739329929-KCCdwb2DENmZaE0VHMs8ZfwRaAGyfFe1-0-6580316c0376a93750cddb3d5769aaa9)
图6-38 运行结果