![Python高效开发实战:Django、Tornado、Flask、Twisted(第3版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/109/40795109/b_40795109.jpg)
1.4 函数
在编程中使用函数可以写出优雅的程序结构,模块化的结构使程序简单化,并提高了可读性和可维护性。读者在本节之前的示例中已接触过Python函数,本节对函数的主要特性进行详细介绍。
1.4.1 定义与使用
Python中函数定义的关键字是def,语法如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/062-4.jpg?sign=1739318604-UkUz90V0FeRR8kSMw9c0VwtiLsJmo4jj-0-03840d34db03bb5d71cf2cf85303e3b9)
Python中函数的返回值可以是零个或任意多个,无须在函数定义中显式声明返回值的数量和类型,只需在函数体中用return关键字返回即可;函数的参数可以有任意个。
【示例1-25】函数的定义和调用演示如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/063-1.jpg?sign=1739318604-TQXmt2uqpyLv4RDc38Yco2pgmQrQAu4v-0-8a7c46cd5fa2ff23bc4603c729a35cff)
代码中定义了3个函数:没有参数和返回值的main()函数、有2个参数和1个返回值的sum()函数、有3个参数和2个返回值的total()函数。将代码保存为func.py,执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/063-2.jpg?sign=1739318604-Dy6xjvAlfgqK5mfScbZ9xEsmnUBLbNGq-0-a76728e4cd0fbc37cceb2828de6f49f6)
【示例1-26】函数参数可以定义默认值,当调用者没有提供参数时,函数在执行过程中用默认值设置该参数。比如:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/063-3.jpg?sign=1739318604-ReJTw4O0px6YMpFPWzoTmmmYDtGETRI0-0-4ce223cb5140e293f013032cdb976d3e)
执行该代码的结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/063-4.jpg?sign=1739318604-sE9w5Lt2ZEt56j6oEFP4UtLg7R5Gqwy9-0-6b0af703244f832258979fe26b963393)
有默认值的参数必须声明在没有默认值的参数之后,不能出现类似如下形式的函数声明:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/064-2.jpg?sign=1739318604-9gX9OJJR3z96TrkNJ9xPVud9P0EnHrs6-0-7fcf4567f79366b5e02c4648c7b82cc0)
【示例1-27】在调用函数时,除了按参数的声明顺序传递参数,还可以不按顺序传递命名参数,如下代码演示了命名参数的函数调用方式:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/064-3.jpg?sign=1739318604-nJp6donXaIwlLELeREPwvwaFdprYSc73-0-10b6f2b99c14180f101b92e1c2d4b34f)
上述代码文件的执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/064-4.jpg?sign=1739318604-xcDfgldgVkzXWrQBx5TglkzmZAI1g5Yn-0-0bf45b0c273bc741b8cb06ca8581a643)
1.4.2 变长参数
变长参数的函数即参数个数可变、参数类型不定的函数。设计一个参数个数可变、参数类型不定的函数,为函数设计提供了更大的灵活性。Python中允许定义两种类型的函数变长参数。
• 元组变长参数:适用于未知参数的数量不固定、但在函数中使用这些参数时无须知道这些参数的名字的场合。在函数定义中,元组变长参数用星号“*”标记。
• 字典(dict)变长参数:适用于未知参数的数量不固定、而且在函数中使用这些参数时需要知道这些参数的名字的场合。在函数定义中,字典变长参数用双星号“**”标记。
【示例1-28】元组变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/064-5.jpg?sign=1739318604-K6pNkyLrcnkEkuM5KgrD3YkCrdKufGJh-0-0ce17578cb9f2258faafdf5809956947)
代码中的show_message是一个带有固定参数message和变长参数tupleName的函数。在调用show_message时,向其传入了固定参数值“Good morning”和若干其他参数。将代码保存为tuple_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/065-2.jpg?sign=1739318604-TrmZKGYmFxfGkCpSKDRBM7TlsY5xFPGb-0-c41ae1385f72e895925acf72e92de05c)
【示例1-29】字典变长参数的使用方法示例如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/065-3.jpg?sign=1739318604-NIcaFsIBNwwakQfK4CuaeCDdw8rQnVo7-0-72d7aacea29e8f4561525dbbb832e735)
代码中的check_book()是一个带有字典变长参数dictParam的函数,它的内容是打印参数内容,并且当检查到书的价格大于100元时,输出“*******I want to buy this book!*******”信息。将代码保存为dictionary_param.py,执行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/065-4.jpg?sign=1739318604-B35O9D1wsMyP0HI06INzEaDzNab3Q01d-0-454404ae796cc0fcfd54a97b31002b42)
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/066-1.jpg?sign=1739318604-aDKiNmOwYPeQ1xr1YYRV7IHalYHTijV5-0-43d1196fd9323165a39b8acb83127975)
1.4.3 匿名函数
匿名函数(Anonymous Function)指一类无须定义标识符(函数名)的函数或子程序,普遍存在于多种编程语言中,一般用于只在代码中存在一次函数引用的场合。Python用lambda语法定义匿名函数,只需用表达式而无须声明。lambda语法的定义如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/066-2.jpg?sign=1739318604-zitqRCTkzwigP6ln13XNErv0mumQtfWY-0-de6852f83914155fc2c5e005f4185b67)
除了没有函数名,其语义与如下函数的定义相同:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/066-3.jpg?sign=1739318604-DJy2FRVEMCN1o9Y6GdC0jSueytC7rqSG-0-3f0ab743f8a7eb5a41e1762ae912e7a1)
lambda函数可以在定义时直接被调用,比如:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/066-4.jpg?sign=1739318604-1trBjMU6wkOazuKMCK9srle10AbPLDBw-0-eee2d49ce9cfce62ddd1cd59dc81efe0)
但通常都是在定义lambda函数的同时,将其作为参数传递给另一个函数,该函数将在其处理过程中对lambda定义的函数进行调用。
【示例1-30】lambda代码的示例如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/067-1.jpg?sign=1739318604-la09sQu26EMvLUjTGAV5TnFZu58aE9wi-0-9b87abecee82c8f045898e6d6d5b297e)
以上代码演示了将lambda函数传递给另一个函数call_func()进行处理的过程。在函数call_func()中,首先通过datetime包中的函数datetime.now()打印时间,然后调用被传递的函数。不仅lambda函数可以作为参数传递给其他函数,普通函数也可以作为参数传递。将代码保存为lambda.py,程序的运行结果如下:
![](https://epubservercos.yuewen.com/B61ED0/21190707201160906/epubprivate/OEBPS/Images/067-2.jpg?sign=1739318604-fjh1jbt3uGgQRTQDgcvxMCEnJo1e555w-0-5ebd5bb4b84d00f3a50ad8f10a9b4a4d)
技巧:用datetime.datetime.now()函数可以获取系统的当前时间。