![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=1738885534-8d1CePZcFLESIXOceqkxey0soq8Y3BjJ-0-2f8023cbcf9474b949ebf12e283166ba)
Python中函数的返回值可以是零个或任意多个,无须在函数定义中显式声明返回值的数量和类型,只需在函数体中用return关键字返回;函数的参数可以是任意个。
【示例1-25】函数的定义和调用演示如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_95.jpg?sign=1738885534-B9kIKpEabOQPfe6xalsWU0JgIcfcxgT1-0-99de561a8c5bceccd4222c3446bea8c1)
代码中定义了3个函数:没有参数和返回值的main()函数、有2个参数和1个返回值的sum()函数、有3个参数和2个返回值的total()函数。将代码保存为func.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_96.jpg?sign=1738885534-S68T9xWhpak7L20bhOQYB6p99go6SIRX-0-e1cdaa39101bd5a913f1d15f02592fc7)
【示例1-26】函数参数可以定义默认值,当调用者没有提供参数时,函数在执行过程中用默认值设置该参数。比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_97.jpg?sign=1738885534-QkVksND6c6e4KTgOL0cGoIx8ZsioucmN-0-ff9f49f1a5f8725410dbfea049bc9108)
执行该代码的结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_98.jpg?sign=1738885534-Dahpr8V9B1K3Po7RuZZ6OlW23W2LSfTy-0-84816b3f29d7823006c1624f88cc2cd9)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_99.jpg?sign=1738885534-yFI9wS1C5youkuFPfCseG9LEmLamw4qm-0-af4576c5d62f69f7f2722721491c08b3)
有默认值的参数必须声明在没有默认值的参数之后,不能出现类似如下形式的函数声明:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_100.jpg?sign=1738885534-xp5tS4tiaqjJRlLQwtZdoFz0PcVhCzlZ-0-b4d5e10807f5cc80e6afad7754f1a747)
【示例1-27】在调用函数时,除了按参数的声明顺序传递参数,还可以不按顺序传递命名参数,如下代码演示了命名参数的函数调用方式:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_101.jpg?sign=1738885534-SklffX6mMn5D0scO8IeKHiq94ucv2F7i-0-31d73ced604dce38fb0fb7d2adc4e980)
上述代码文件的执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_102.jpg?sign=1738885534-xoMiF8WCr1qurFnVQjEU3h7F8uayTrIW-0-a97ce00269ded864759549bdb5ccf715)
1.4.2 变长参数
变长参数的函数即参数个数可变、参数类型不定的函数。设计一个参数个数可变、参数类型不定的函数为函数设计提供了更大的灵活性。Python中允许定义两种类型的函数变长参数。
· 元组变长参数:适用于未知参数的数量不固定,但在函数中使用这些参数时无须知道这些参数的名字的场合。在函数定义中,元组变长参数用星号“∗”标记。
· 字典(dict)变长参数:适用于未知参数的数量不固定,而且在函数中使用这些参数时需要知道这些参数的名字的场合。在函数定义中,字典变长参数用双星号“∗∗”标记。
【示例1-28】元组变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_103.jpg?sign=1738885534-9vtF8hOHjrmcIb7tvHawsmri19pshZc5-0-475e0a2b70b85788f3603298847a3a38)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_104.jpg?sign=1738885534-7fD4vJmLTEBfmTsJCpvzzaYRQysRrjbf-0-0ea553be06d210814fd32c44b4fdbaa2)
代码中的show_message是一个带有固定参数message和变长参数tupleName的函数。在调用show_message时向其传入了固定参数值“Good morning”和若干个其他参数。将代码保存为tuple_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_105.jpg?sign=1738885534-NThfDdsncXTk7RrSWUfodnXJrhHGEGXL-0-9ec4dcbde140c162145ca1659b8976b9)
【示例1-29】字典变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_106.jpg?sign=1738885534-qJHlSOCLbyiXQV65qkWzjNmkT0wT0i8l-0-b168325432d3761687c1f8068ae9a0ce)
代码中的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=1738885534-MCF84DS0Ug0ICfhOFNOG3YypBa3GlOT3-0-fdcf763980ab3d6f20204c48847aaf92)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_108.jpg?sign=1738885534-LrAZNuKcIjKYZyDYw8nU9hbCFbyjKNjG-0-de1e58c1411d13ad0bc06a8ca996ba37)
1.4.3 匿名函数
匿名函数(Anonymous Function)是指一类无须定义标识符(函数名)的函数或子程序,普遍存在于多种编程语言中,一般用于只在代码中存在一次函数引用的场合。Python用lambda语法定义匿名函数,只需用表达式而无须声明。lambda语法的定义如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_109.jpg?sign=1738885534-IXayHKOmCvKS26EhZGtjXmLrjcpN3W9U-0-295da2b32615bfb5bd22fd52eebbe780)
除了没有函数名,其语义与如下函数的定义相同:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_110.jpg?sign=1738885534-QQkTerILDbhEcTJcjrd78JZ2CIHqumRU-0-c2925ea06239bf6504fef04982a125ad)
lambda函数可以在定义时直接被调用,比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_111.jpg?sign=1738885534-SiO6dbV9CFbhSXB2FRorrkKxXjJNH5Rf-0-33f541a69b253cdc1ea8b2e70eb71cf7)
但通常都是在定义lambda函数的同时将其引用作为参数传递给另一个函数,该函数将在其处理过程中对lambda定义的函数进行调用。
【示例1-30】lambda代码的示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_112.jpg?sign=1738885534-mWtjC3gEaFJIeRsvgSelUwa2qgxKiKZu-0-dd806aea438a1adcf6b02e2ff04985bf)
以上代码演示了将lambda函数传递给另外一个函数call_func()进行处理的过程,在函数call_func()中首先通过datetime包中的函数datetime.now()打印时间,然后调用被传递的函数。不仅lambda函数可以作为参数传递给其他函数,普通函数也可以作为参数传递。将代码保存为lambda.py,程序的运行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_113.jpg?sign=1738885534-SV2j6WgTpZQJJxEOT7dXbd1LRjbLFk6M-0-f309ed96947bac65e29231006e60064d)
技巧:用datetime.datetime.now()函数可以获取系统的当前时间。