![Python高效开发实战:Django、Tornado、Flask、Twisted(第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/478/25462478/b_25462478.jpg)
1.4 函数
在编程中使用函数可以写出优雅的程序结构,模块化的结构使程序简单化,并提高了可读性和可维护性。读者在本章之前的示例中已接触过Python函数,本节对函数的主要特性进行详细学习。
1.4.1 定义与使用
Python中函数定义的关键字是def,语法如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_94.jpg?sign=1739295234-4ly7YZenR1GmtWXYm2ClKc9VHBTrwNPZ-0-1f019b706fd578f26c782eadb67fd53d)
Python中函数的返回值可以是零个或任意多个,无须在函数定义中显式声明返回值的数量和类型,只需在函数体中用return关键字返回;函数的参数可以是任意个。
【示例1-25】函数的定义和调用演示如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_95.jpg?sign=1739295234-AyNALlbhJi9HkQkRGzOgVC4A0vP2U5DH-0-03bfa4e8c929360ed6075124c89bd699)
代码中定义了3个函数:没有参数和返回值的main()函数、有2个参数和1个返回值的sum()函数、有3个参数和2个返回值的total()函数。将代码保存为func.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_96.jpg?sign=1739295234-iavQ3sx3UEHw7Ii74Bzy8he6OkDI9msR-0-498235d64fabbdded2a4ed0c80362455)
【示例1-26】函数参数可以定义默认值,当调用者没有提供参数时,函数在执行过程中用默认值设置该参数。比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_97.jpg?sign=1739295234-9khfrjJsUDttvfPWIIUv39xZCtpUZhDx-0-26032ccbdbd0a480a23940beb7686cc3)
执行该代码的结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_98.jpg?sign=1739295234-r8I5CWaKsqmxlt7vCCyBRHGVQmjjSOYo-0-99ef2625a99352a3e7c0dae395c5d190)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_99.jpg?sign=1739295234-GvN1hGVzViGIDLKVicD3YqWev7jbMXcr-0-06fc1f0bb5fce860a9754134321a39d0)
有默认值的参数必须声明在没有默认值的参数之后,不能出现类似如下形式的函数声明:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_100.jpg?sign=1739295234-0FsVxchMywhH1HlELWqnNM51h2EmDZ6B-0-0b96a0fb98fa011ebaa91969eb3166d8)
【示例1-27】在调用函数时,除了按参数的声明顺序传递参数,还可以不按顺序传递命名参数,如下代码演示了命名参数的函数调用方式:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_101.jpg?sign=1739295234-nQXPvZqK3pniR5tnq6UsyJIYd6peaQaX-0-876aea0a3783d55ac419dfee0db6a43d)
上述代码文件的执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_102.jpg?sign=1739295234-tV6UCq8cN8kJv3ga1g8oHHTHR6Xzy2bk-0-0c2365bc881523b1be2853a477c0f997)
1.4.2 变长参数
变长参数的函数即参数个数可变、参数类型不定的函数。设计一个参数个数可变、参数类型不定的函数为函数设计提供了更大的灵活性。Python中允许定义两种类型的函数变长参数。
· 元组变长参数:适用于未知参数的数量不固定,但在函数中使用这些参数时无须知道这些参数的名字的场合。在函数定义中,元组变长参数用星号“∗”标记。
· 字典(dict)变长参数:适用于未知参数的数量不固定,而且在函数中使用这些参数时需要知道这些参数的名字的场合。在函数定义中,字典变长参数用双星号“∗∗”标记。
【示例1-28】元组变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_103.jpg?sign=1739295234-qHwVN45DsGGdRPhduBsmENt2UJWdhK6l-0-d580ded29109c78cfddc6a2565fa5888)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_104.jpg?sign=1739295234-XqAzSR16P9TWgYSQr9b5PmaIlDWLBwCK-0-cb1f729a63ab34a26530c7825c40cb0e)
代码中的show_message是一个带有固定参数message和变长参数tupleName的函数。在调用show_message时向其传入了固定参数值“Good morning”和若干个其他参数。将代码保存为tuple_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_105.jpg?sign=1739295234-Wbr4pNVeFTFfpE45WnzdiEGgMWqy2oPF-0-7ea1365b36a5ad391e97ef3d8039dd6d)
【示例1-29】字典变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_106.jpg?sign=1739295234-lFw0DmzesSBMUlOD6fDR23IKnVFax4PS-0-f0fcfbd692ded2a1fa2edcad27117c06)
代码中的check_book()是一个带有字典变长参数dictParam的函数,它的内容是打印参数内容,并且当检查到书的价格大于100元时,输出“∗∗∗∗∗∗∗I want buy this book!∗∗∗∗∗∗∗”信息。将代码保存为dictionary_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_107.jpg?sign=1739295234-ZxiGyyCd4L4vppjH4pNNPACPFOW3Sg1Z-0-f0c1e74d0aff5eba1d321429758f8b80)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_108.jpg?sign=1739295234-KOREvIFDOOl2Oq8HnlmrHK2pub2PeHg3-0-566bd3c8603e201b7ae4ed8094b7f8b8)
1.4.3 匿名函数
匿名函数(Anonymous Function)是指一类无须定义标识符(函数名)的函数或子程序,普遍存在于多种编程语言中,一般用于只在代码中存在一次函数引用的场合。Python用lambda语法定义匿名函数,只需用表达式而无须声明。lambda语法的定义如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_109.jpg?sign=1739295234-7P9xTCiKooR4oKCtf32At0xOlIuaMpVm-0-1f06b029679e9737a96022e1d3fcc153)
除了没有函数名,其语义与如下函数的定义相同:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_110.jpg?sign=1739295234-AAhyghfpYbOQDws8nYnEuwdS2bBFxb7g-0-dcf09671f82f77e4da6a082b3698054f)
lambda函数可以在定义时直接被调用,比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_111.jpg?sign=1739295234-f3EsyTAKfcgYgn4VzkPktJHvry3pGuHh-0-3a492e2587ed8258fb56035e439a7532)
但通常都是在定义lambda函数的同时将其引用作为参数传递给另一个函数,该函数将在其处理过程中对lambda定义的函数进行调用。
【示例1-30】lambda代码的示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_112.jpg?sign=1739295234-KP5X0bi1QkAwgXNZWtfwAhE3h8AnoJtY-0-15459bd121c41027a6273b9d15f0a802)
以上代码演示了将lambda函数传递给另外一个函数call_func()进行处理的过程,在函数call_func()中首先通过datetime包中的函数datetime.now()打印时间,然后调用被传递的函数。不仅lambda函数可以作为参数传递给其他函数,普通函数也可以作为参数传递。将代码保存为lambda.py,程序的运行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_113.jpg?sign=1739295234-HSvXQE3Xo0pYiDMIoU07PAVROVSuwhc3-0-962dd4cfd0cd92f275da7556d8c84387)
技巧:用datetime.datetime.now()函数可以获取系统的当前时间。