一. 匿名函数
匿名函数是一类无须定义标识符的函数,它与普通函数一样可以在程序的任何位置使用,但是在定义时被严格限定为单一表达式。Python中使用关键字lambda来定义匿名函数。
语法格式如下:
#用f存储这个函数,以便被调用
f = lambda x, y: x + y
print(f(10, 20))
这个语句等价于如下正常函数的定义:
def 函数名(参数列表):
return表达式
与普通的函数相比,lambda函数的体积更小、功能单一,用于定义简单的、能在一行内表示的函数,返回一个函数类型。
与普通函数的区别:
- 普通函数在定义时有名称,而lambda函数没有。
- 普通函数的函数体中可以包含多条语句,而lambda函数只能是一个表达式。普通函数可以实现比较复杂的功能,而lambda函数功能简单。
- 普通函数能被其他程序调用,而lambda函数不能被其他程序调用(不能模块化?),
经常用一个变量来保存它,以便后期可以随时使用这个函数
。
lambda函数经常会用在多维列表的排序中。如对二维列表按第二列排序分别升序、降序排序,示例代码如下:
ls = [['a', 100], ['b', 10], ['c', 30], ['d', 90], ['e', 50]]
ls.sort(key=lambda x: x[1]) # 取第二位的数
print(ls)
二. 将函数存储在模块中
模块化设计是使用函数和对象设计程序的思考方法,以功能块为基本单位,一般有两个基本要求:
- 高内聚。尽可能地合理划分功能块,功能块内部耦合紧密。
- 低耦合。模块间尽可能简单,功能块之间耦合度低。
- 耦合是指两个实体相互依赖于对方的一个量度,在程序设计结构中是指各模块之间相互关联的程序。
- 衡量模块独立性的定性标准是内聚(一个模块内各个元素彼此结合的紧密程度)和耦合(一个软件结构内不同模块之间互连程度的度量)。
模块化编程可采用以下步骤进行:
- 分析问题,明确需要解决的任务。
- 对任务进行逐步分解和细化,分成若干个子任务,每个子任务只完成部分完整功能,并且可以通过函数实现。
- 确定模块(函数)之间的调用关系。
- 优化模块之间的调用关系。
- 在主函数中进行调用实现。
语法
- 可以将函数存储在称为模块的独立文件中,再将模块导入到主程序中。
- import语句允许在当前运行的程序文件中使用模块中的代码。
作用
- 通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上。
- 这还能让你在众多不同的程序中重用函数。
- 将函数存储在独立文件中后,可与其他程序员共享这些文件而不是整个程序。
- 使用其他程序员编写的函数库。
1. 导入整个模块
要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。
下面来创建一个包含函数make_pizza()的模块: pizza.py
def make_pizza(size, *toppings):
"""概述要制作的比萨。"""
print(f"\nMaking a {size}-inch pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")
创建调用making_pizzas.py文件
只需编写一条import语句并在其中指定模块名,就可在程序中使用该模块中的所有函数。
import pizza
if __name__ == '__main__':
pizza.make_pizza(16,'pepperoni')
pizza.make_pizza(12,'mushrooms','green peppers','extra cheese')
# Making a 16-inch pizza with the following toppings:
# - pepperoni
#
# Making a 12-inch pizza with the following toppings:
# - mushrooms
# - green peppers
# - extra cheese
如果使用这种import语句导入了名为module_name.py的整个模块,就可使用下面的语法来使用其中任何一个函数:
module_name.function_name()
2. 导入特定的函数
还可以导入模块中的特定函数,这种导入方法的语法如下:
from module_name import function_name
通过用逗号分隔函数名,可根据需要从模块中导入任意数量的函数:
from module_name import function_0, function_1, function_2
对于前面的making_pizzas.py示例,如果只想导入要使用的函数,代码将类似于下面这样:
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
3. 使用as给函数指定别名
如果要导入函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名:函数别名。
下面给函数make_pizza()指定了别名mp()。
这是在import语句中使用make_pizza as mp实现的,关键字as将函数重命名为指定的别名
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
指定别名通用语法:
from module_name import function_name as fn
4. 使用as给模块指定别名
import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
给模块指定别名的通用语法如下:
import module_name as mn
5. 导入模块中的所有函数(不推荐)
使用星号(*)运算符可让Python导入模块中的所有函数:
from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
由于导入了每个函数,可通过名称来调用每个函数,而无须使用句点表示法。
但注意:使用并非自己编写的大型模块时,最好不要采用这种导入方法。
这是因为如果模块中有函数的名称与当前项目中使用的名称相同,可能导致意想不到的结果:Python可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数。
最佳的做法是,要么只导入需要使用的函数,要么导入整个模块并使用句点表示法。
三. 函数编写指南
编写函数时,需要牢记几个细节。
-
应给函数指定描述性名称,且只在其中使用小写字母和下划线。给模块命名时也应遵循上述约定。
-
每个函数都应包含简要地阐述其功能的注释。该注释应紧跟在函数定义后面,并采用文档字符串格式。文档良好的函数让其他程序员只需阅读文档字符串中的描述就能够使用它。
-
给形参指定默认值时,等号两边不要有空格
def function_name(parameter_0, parameter_1='default value')
调用函数中的关键字实参,也应遵循这种约定:
function_name(value_0, parameter_1='value')
-
如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,这样将更容易知道前一个函数在什么地方结束,下一个函数从什么地方开始。
-
所有import语句都应放在文件开头。唯一例外的情形是,在文件开头使用了注释来描述整个程序。
-
PEP 8建议代码行的长度不要超过79字符,这样只要编辑器窗口适中,就能看到整行代码。如果形参很多,导致函数定义的长度超过了79字符,可在函数定义中输入左括号后按回车键,并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体区分开来。
def function_name( parameter_0, parameter_1, parameter_2, parameter_3, parameter_4, parameter_5): function body...