一个简单的示例:
def greet_user():
"""显示简单的问候语"""
print("hello!")
greet_user()
上面的代码显示了最简单的函数结构,使用关键字def来定义函数,紧跟着函数名,括号可以指出函数完成需要的信心,最后以冒号结尾。紧跟着后面所有的缩进行构成函数体。函数相关文档描述可以使用三引号括起,要调用函数可以依次指定函数名以及括号括起的必要信息。
如果需要给函数传递信息,则如下代码所示:
def greet_user(username):
print("hello, " + username.title()+"!")
greet_user("jesse")
greet_user(“jesse”)调用函数并且传递参数,则会打印hello,Jesse。
实参形参概念不多介绍。
函数定义可以包含多个形参,因此函数调用也可以包含多个实参,向函数传递实参的方法有位置实参(要求实参的顺序与形参的顺序相同),也可以使用关键字形参(每个实参都由变量名和值组成),还可以使用列表和字典。
位置实参,即函数调用中的的每个实参都关联到函数定义的一个形参。
关键字实参是传递给函数的名称-值对,直接在是惨重将名称和值关联起来,如下代码:
def describe_pet(animal_type, pet_name):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
# 关键字实参
describe_pet(animal_type='hamster', pet_name='harry')
# 位置实参
describe_pet('dog', 'willie')
函数定义两种方法是一样的,但是调用时,位置实参只需要传递实参即可,而关键字实参需要指定实参和哪一个形参对应。
编写函数时可以给每个形参指定默认值,调用函数过程中如果给出了实参,则使用实参,没有给出则使用默认值。因此指定默认值之后可以在函数调用时省略相对应的实参。
def describe_pet(pet_name,animal_type='dog'):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('willie')
如果使用默认值,再使用位置实参调用时需要注意位置,因此一般默认值放在最后,否则只能使用关键字实参。如果不需要使用默认值则需要显式的指定。
由于可以使用多种方式函数参数,函数调用也有多种等效调用方式。
函数可以使用return语句将值返回到调用函数的代码行。python的返回值并不需要在函数前声明返回类型,只需要在函数体中添加返回语句即可。
通过关键字实参可以使实参变为可选的,将可选参数放在参数最后一个并指定一个默认值,便可以使实参变为可选的。
函数可以返回任何类型的值,包括列表和字典等复杂的数据结构。如下:
def build_person(first_name,lastname):
"""返回一个字典,包含一个人的信息"""
person = {'first':first_name,'last':last_name}
return person
musician = build_person('jimi','hendrix')
print(musician)
上面代码在函数体内建立了一个字典,同时将函数传入的实参作为字典的值,最后返回字典。函数参数也可以多加一个参数,作为字典的另外的关键字的值。
函数可以与前面所学的结构结合起来,如下代码:
def get_formatted_name(first_name,last_name):
"""返回整洁的姓名"""
full_name = first_name + last_name
return full_name.title()
while True:
print("please tell me your name:")
print("(enter 'q' at any time to quit)")
f_name = input("first_name:")
if f_name == 'q':
break
l_name = input("last_name:")
if l_name == 'q':
break
formattted_name = get_formatted_name(f_name,l_name)
print("\nHello, "+formattted_name + "!")
函数参数也可以是列表,列表包含的可以是名字、数字、字典等。假设有一个用户列表,可以适用如下函数:
def greet_user(names):
"""向列表中的每位用户发出问候"""
for name in names:
msg = "hello " + name.title() + "!"
print(msg)
usernames = ['hannah','ty','margot']
greet_user(usernames)
函数可以接受一个列表,并且遍历列表中每一个元素。
同样在函数中可以修改列表的值,这种修改是永久的,类似与C、C++中传递指针。如果需要禁止函数修改列表,则需要传递列表的副本给函数,可以采用切片法创建列表的副本。
function_name(list_name[:])
如果有时候不确定函数需要接受多少个实参,可以使用如下方法接受任意数量实参。
def make_pizza(*toppings)
"""打印配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
形参名中的*,也就创建了一个名为toppings的空元组,并将收到的所有值都封装在这个元组里。
如果要让函数接收不同类型的实参,那么接受任意数量的形参应该放在最后,先匹配位置实参和关键字实参,最后剩下的实参收集到最后一个形参中。
def make_pizza(size, *toppings):
"""概述要制作的比萨"""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
如果需要接受任意数量的实参,但是不知道要传递给函数的是什么样的信息,可以将函数编写成能够接受任意数量的键-值对,如下代码:
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)
函数返回一个字典,包含用户的姓名,如果提供额外的键值对也可以处理。
函数的优点是可以与主程序分离。可以通过将函数存储在模块的独立文件中,再将模块导入到主程序中,import语句可以允许在当前运行的程序文件中使用模块的代码,通过将函数存储在独立的文件中可以隐藏程序代码细节,重点可以放在程序高层逻辑上。
要导入模块则首先创建模块,模块是扩展名为.py的文件,包含要导入到程序中的代码。如下图创建一个名为pizza.py的模块。
之后在同文件下编写程序,如下图
之后执行该程序结果如下:
上面是一种导入方法,只需要编写一条import语句并指定模块名,则可以使用该模块中的所有函数。使用方法如下代码
module_name.function_name()
同时还可以导入模块中指定函数,模块和上一节一样,在程序中修改,如下图:
再执行程序,结果如下:
结果与之前一样,可以看出如果想要只导入模块中的一个函数可以使用如下代码:
from module_name import function_name
可以通过逗号分隔函数名,可以根据需要导入任意数量的函数
from module_name import function_0, function_1, function_2
如果使用这种导入方式,在调用函数时则不需要使用句点,因为在import语句中显式的导入了函数,无需指定模块名。
如果要导入的函数名与现有程序函数名冲突或者函数名太长,可以指定简短而独一无二的别名,要指定这种别名要在导入时这样做。还是以之前的模块为例,如下:
执行程序结果还和之前结果一样。指定别名的通用语法如下:
from module_name import function_name as fn
import module_name as mn
如下图:
运行结果仍一样。*可以将模块中的所有函数都复制到这个程序文件中,由于导入每个函数,可以通过名称调用每个函数,无需使用句点表示法,如果不是自己编写的模块最好不要使用这种方法。
每个函数都要简述其功能,注释应紧跟在函数定义之后,采用文档字符串格式。
给形参指定默认值时,等号两边不要有空格,对于函数调用中的关键字实参也遵循这种约定。
代码长度不要超过79字符,如果形参较多,可以在函数定义中输入左括号后按回车键并在下一行按两次Tab键,从而将形参列表和只缩进一层的函数体分开。如下:
def function_name(
parameter_0, parameter_1, parameter_2,
parameter_3, parameter_4, parameter_5):
function body...
如果程序或函数包含多个函数,可以使用两个空行将相邻的函数分开。
所有import语句都应该放在文件开头,唯一例外是在文件开头使用了注释来描述整个程序。