- Python高效开发实战:Django、Tornado、Flask、Twisted(第2版)
- 刘长龙
- 1214字
- 2020-08-27 23:13:39
1.4 函数
在编程中使用函数可以写出优雅的程序结构,模块化的结构使程序简单化,并提高了可读性和可维护性。读者在本章之前的示例中已接触过Python函数,本节对函数的主要特性进行详细学习。
1.4.1 定义与使用
Python中函数定义的关键字是def,语法如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_94.jpg?sign=1739662129-FZOe6GP9w47SaHomQhhr9Uknc8qB85Pe-0-6a5ef551b53b1f3fe0265a66f9a89a35)
Python中函数的返回值可以是零个或任意多个,无须在函数定义中显式声明返回值的数量和类型,只需在函数体中用return关键字返回;函数的参数可以是任意个。
【示例1-25】函数的定义和调用演示如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_95.jpg?sign=1739662129-3KZAWkBkIKKmJUJVQvmoEptsPqcR810j-0-67f545424423326724565eb6609f0421)
代码中定义了3个函数:没有参数和返回值的main()函数、有2个参数和1个返回值的sum()函数、有3个参数和2个返回值的total()函数。将代码保存为func.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_96.jpg?sign=1739662129-m1BeJl71lLd28vsyIysUszEZFLIYIC1H-0-b9e65be7da83cfdea09e084048ba51cb)
【示例1-26】函数参数可以定义默认值,当调用者没有提供参数时,函数在执行过程中用默认值设置该参数。比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_97.jpg?sign=1739662129-W6rdABYkwK9ABhdES1rAWSP2mGAYe2Jf-0-70c0e90132f9d7c8271dc0cf55c82512)
执行该代码的结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_98.jpg?sign=1739662129-pSeLfp4tF81MBTFHxukgzAjRasrjDexv-0-8f6a1c54759f92cbd4fad1906df0816f)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_99.jpg?sign=1739662129-FtB3vigN3yUCSVFrSp3ZJ7fxIBx47eN0-0-f7c3649fb532a390ebe07017b63f6889)
有默认值的参数必须声明在没有默认值的参数之后,不能出现类似如下形式的函数声明:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_100.jpg?sign=1739662129-cjME1RUpbQHhcHOBv39UnU7WK58lZlXp-0-58c94feb81efdf847a46960316f79082)
【示例1-27】在调用函数时,除了按参数的声明顺序传递参数,还可以不按顺序传递命名参数,如下代码演示了命名参数的函数调用方式:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_101.jpg?sign=1739662129-9v4WFKDIwUckS8L8HKuzNA5bYvDxJzlj-0-6c8a7102c0b969665e12fc86965ca539)
上述代码文件的执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_102.jpg?sign=1739662129-3NfODZKub3ot4DGxIittFkYLwdDx8rFb-0-5e6a677a5130aca8b594e5c14077c2ce)
1.4.2 变长参数
变长参数的函数即参数个数可变、参数类型不定的函数。设计一个参数个数可变、参数类型不定的函数为函数设计提供了更大的灵活性。Python中允许定义两种类型的函数变长参数。
· 元组变长参数:适用于未知参数的数量不固定,但在函数中使用这些参数时无须知道这些参数的名字的场合。在函数定义中,元组变长参数用星号“∗”标记。
· 字典(dict)变长参数:适用于未知参数的数量不固定,而且在函数中使用这些参数时需要知道这些参数的名字的场合。在函数定义中,字典变长参数用双星号“∗∗”标记。
【示例1-28】元组变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_103.jpg?sign=1739662129-yPVK5zPZZlvISfFvSqXs67vV8sgGjT6I-0-192eeeaf652533e0fe3d80f9417e662d)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_104.jpg?sign=1739662129-zdZfTMz8UB4QDDGJMytU6O99nhWY9MSZ-0-209e3cb9c07974fc65770009b4a299a7)
代码中的show_message是一个带有固定参数message和变长参数tupleName的函数。在调用show_message时向其传入了固定参数值“Good morning”和若干个其他参数。将代码保存为tuple_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_105.jpg?sign=1739662129-aJdmuQ3tbDNqpgv63nQH19BmvJ9skXqA-0-2a21afd2573deae5196acb0f3431e64f)
【示例1-29】字典变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_106.jpg?sign=1739662129-rOz0RKZmb8wtmqJUxM29GjP9lhwcsu0n-0-c5ad7dc758da2dc30b1d0c878c50f4a4)
代码中的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=1739662129-0MFbpzrgSPIe0vFOrNohodni6zJ5upwg-0-fad4d69c0da37e73e7445dc2e62e5c47)
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_108.jpg?sign=1739662129-jWfeWcjwyhlTyUkCs8D0ijLHej1bF4S3-0-1f87451fab1f96eff93754bfc61f8c6b)
1.4.3 匿名函数
匿名函数(Anonymous Function)是指一类无须定义标识符(函数名)的函数或子程序,普遍存在于多种编程语言中,一般用于只在代码中存在一次函数引用的场合。Python用lambda语法定义匿名函数,只需用表达式而无须声明。lambda语法的定义如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_109.jpg?sign=1739662129-60M7DtJlW8uYHHDTbn7Oj9jl9yOgLSKY-0-37e332b1182b19ac671231ed55adac7b)
除了没有函数名,其语义与如下函数的定义相同:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_110.jpg?sign=1739662129-gA2Bpyal3fDZq5J0qSNlUJF7YMxDchnA-0-aa8746ca50301d0f2c1736cb987b4013)
lambda函数可以在定义时直接被调用,比如:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_111.jpg?sign=1739662129-0qlKKYISAJm2LVrbushi2xMdwJOkNyRh-0-69d89f2b40081d2784b5644c21dbb6e2)
但通常都是在定义lambda函数的同时将其引用作为参数传递给另一个函数,该函数将在其处理过程中对lambda定义的函数进行调用。
【示例1-30】lambda代码的示例如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_112.jpg?sign=1739662129-WBXGoxzHrV2E9vgtTN4XUz0jzEJ77UoQ-0-7f502082df9b1832675c09aa0981e89f)
以上代码演示了将lambda函数传递给另外一个函数call_func()进行处理的过程,在函数call_func()中首先通过datetime包中的函数datetime.now()打印时间,然后调用被传递的函数。不仅lambda函数可以作为参数传递给其他函数,普通函数也可以作为参数传递。将代码保存为lambda.py,程序的运行结果如下:
![](https://epubservercos.yuewen.com/AB22F5/13916126403781606/epubprivate/OEBPS/Images/txt002_113.jpg?sign=1739662129-SJWyLeOfHgFO2FnhdYrXQuoJ3pg2Q6ka-0-4218d98ae51918cf50dd2c3085b7317e)
技巧:用datetime.datetime.now()函数可以获取系统的当前时间。