函数是带名字的代码块,用于完成具体的工作。需要再程序中多次执行同一项任务时,可以调用执行该任务的函数来处理。通过使用函数,程序的编写、阅读、测试和修复都将更容易。
1.定义函数
def greet_user():
"""显示简单的问候语"""
print("Hello!")
greet_user()
========================================================
Hello!
注:函数的定义以冒号结尾,及时没有传递任何信息,括号也必不可少。
2.函数传递信息
def greet_user(username):
"""显示简单的问候语"""
print("Hello, " + username.title() + "!")
greet_user('dylan king')
========================================================
Hello, Dylan King!
从上面例子可以看出,Python中函数参数无需指定类型,只跟传入的实参类型有关。
在函数 greet_user() 的定义中,变量 username 是一个形参——函数完成其工作所需的一项信息。在代码 greet_user('dylan king') 中,值 ‘dylan king’就是一个实参。实参是调用函数时传递给函数的信息。我们调用函数时,将要让函数使用的信息放在括号中。在 greet_user('dylan king') 中,将实参 'dylan king' 传递给了函数 greet_user(),这个值被存储在形参username中。
3.传递实参
Python 必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式就是基于实参的顺序。这种关联方式被称为位置实参。
位置实参的传递一定要注意对应形参的位置。如果担心位置会写错,可以用关键字实参。关键字实参是传递给函数的名称-值对。
def describe_pet(animal_type, pet_name):
"""显示宠物信息"""
print("
I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('harry', 'hamster')
describe_pet(pet_name = 'harry', animal_type = 'hamster')
describe_pet(animal_type = 'harry', pet_name = 'hamster')
========================================================
I have a harry.
My harry's name is Dog.
I have a hamster.
My hamster's name is Harry.
I have a harry.
My harry's name is Hamster.
有时候我们想这个函数能够被更多的程序调用,但是有些形参在调用的时候完全不用给值,这个时候我们可以考虑给形参指定默认值。
def describe_pet(animal_type, pet_name='dog'):
"""显示宠物信息"""
print("
I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('harry')
========================================================
I have a harry.
My harry's name is Dog.
注意:使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出又默认值的形参。这让Python依然能够正确地解读位置实参。默认值可以指定为空字符,表示这个形参的传入实参时可选的。例如:
def describe_pet(animal_type, pet_name = ''):
"""显示宠物信息"""
print("
I have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('harry')
========================================================
I have a harry.
My harry's name is .
4.函数返回值
函数返回的值被称为返回值。在函数中,可使用 return 语句将值返回到调用函数的代码行。返回值可以是简单的数字、字符也可以是字典、列表、元组这种复杂的数据结构。函数可返回任何类型的值。
返回简单值:
def get_formatted_name(first_name, last_name):
"""返回整洁的姓名"""
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
========================================================
Jimi Hendrix
返回字典:
def build_person(first_name, last_name):
"""返回一个字典,其中包含有关一个人的信息"""
person = {'first':first_name, 'last':last_name}
return person
musician = build_person('jimi', 'hendrix')
print(musician)
========================================================
{'first': 'jimi', 'last': 'hendrix'}
5.传递列表
def greet_users(names):
"""向列表涨的每位用户都发出简单的问候"""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
========================================================
Hello, Hannah!
Hello, Ty!
Hello, Margot!
注意:以上例子传递的是列表的地址,所以在函数中对列表的任何操作都是永久性的。如果想禁止函数修改列表,可使用列表切片复制列表。
def greet_users(names):
"""向列表涨的每位用户都发出简单的问候"""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames[:])
6.传递任意数量的实参
有时候,你预先不知道函数需要接收多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。
例如:
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
========================================================
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')
从上例子可以看出形参名 *toppings 中的 星号 让Python创建一个名为 toppings 的 空元祖,并将收到的所有值都封装到这个元组中。所以如果你不知道函数到底要接收多少个实参,可以定义一个带星号的形参名即可。然后你可以通过引用这个元组来得到你传入的实参。
7.创建任意数量的关键字实参
有时候,需要接受任意数量的实参,但预先不知道传递给函数的是什么样的信息。再这种情况下,可将函数编写成能够接受任意数量的键-值对——调用语句提供了多少就接受多少。
例如:
def build_profile(first, last, **user_info):
"""创建一个字典,其中包含我们知道的有关用户的一切"""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('albert', 'einstein', location = 'princeton', field = 'physics')
print(user_profile)
========================================================
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
从上例子可以看出形参 **user_info 中的 两个星号 让Python创建了一个名为user_info的 空字典,并将收到的所有名称-值对都封装到了这个字典中。所以如果你想传递给函数名称-值对,但是又不知道有多少的时候你可以定义一个带两个星号的形参名即可。然后你可以通过引用这个字典来得到你传入的实参值。
8.函数的使用
函数的优点之一是,使用它们可以将代码块和主程序分离。通过给函数指定描述性名称,可让主程序容易理解得多。你还可以更进一步,将函数存储再被称为模块得独立文件中,再将模块导入到主程序中。
import 语句允许再当前运行的程序文件中使用模块中的代码。
8.1.导入整个模块
要让函数是可导入的,得先创建模块。模块是扩展名为.py得文件,包含要导入到程序中得代码。例如
我们先创建一个包含 make_pizza() 函数的模块。模块文件名为pizza.py
def make_pizza(size, *toppings):
"""概述要制作的披萨"""
print("
Making a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
再在pizza.py所在的文件目录中创建另外一个名为 make_pizzas.py 的文件,这个文件导入刚创建的模块,再调用make_pizza()函数两次:
import pizza
pizza.make_pizza(16,'peppernoi')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
========================================================
Making a 16-inch pizza with the following toppings:
- peppernoi
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
如上例所示如果要调用被导入模块中的函数,可指定导入的模块名称pizza和函数名make_pizza(),并用句点分隔。基本语法如下:
module_name.function_name()
8.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,'peppernoi')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
8.3.使用 as 给模块和函数指定别名
如果要导入的函数/模块的名称可能与程序中现有的名称冲突,或者函数/模块的名称太长,可指定简短而独一无二的别名——函数/模块的另一个名称,类似于外号。
指定别名的通用语法如下:
函数取别名
from module_name import function_name as fn
模块取别名
import module_name as mn
8.4.导入模块中所有函数
使用星号(*)运算符可让Python导入模块中的所有函数:
from pizza import *
make_pizza(16,'peppernoi')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
语法如下:
from module_name import *
9.函数编写规范
- 函数的名称必须具有描述性,且只在其中使用小写字母和下划线
- 每个函数都应该包含简要的功能注释,并采用文档字符串格式
- 给形参默认值时,等号两边不要有空格
- 在形参列表中必须先列出没有默认值的形参,再列出又默认值的形参
- 模块中如果有多个函数用两个空行隔开
- 每行代码长度不要超过79个字符(PEP 8建议)
- 所有import语句都应放在开头,除非开头写了注释用来描述整个程序