1函数定义
def greet_user():
"""显示简单的问候语"""
print("Today is Sunday!")
greet_user()
>>>Today is Sunday!
紧跟在def greet_user(): 后面的所有缩进行构成了函数体。第二行的文本是被称为文档字符串 (docstring)的注释,描述了函数是做什么的。文档字符串用三引号括起,Python使用它们来生成有关程序中函数的文档。
#传递参数
def greet_user(username):
"""显示简单的问候语"""
print(username.title() + ",Today is Sunday!")
greet_user('Jude')
>>>Jude,Today is Sunday!
2传递实参
2.1位置实参:实参的顺序与形参的顺序相同(顺序一致)
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('hamster','harry')
>>>I have a hamster.
>>>My hamster's name is Harry.
2.2关键字实参
关键字实参是传递给函数的名称—值对。直接在实参中将名称和值关联起来了,关键字实参无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
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')
>>>I have a hamster.
>>>My hamster's name is Harry.
关键字实参的顺序无关紧要,因为Python知道各个值该存储到哪个形参中。
注意 使用关键字实参时,务必准确地指定函数定义中的形参名。
2.3默认值
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(pet_name='harry')
>>>I have a dog.
>>>My dog's name is Harry.
编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。
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(pet_name='harry',animal_type='cat')
>>>I have a cat.
>>>My cat's name is Harry.
注意:由于给animal_type 指定了默认值,无需通过实参来指定动物类型,因此在函数调用中只包含一个实参:宠物的名字。然而,Python依然将这个实参视为位置实参,因此如果函数调用中只包含宠物的名字,这个实参将关联到函数定义中的第一个形参。否则会报错:
def describe_pet(animal_type='dog',pet_name):
"""显示宠物信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(pet_name='harry')
>>>SyntaxError: non-default argument follows default argument
即使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。这让Python依然能够正确地解读位置实参。
2.4混合使用位置实参,关键值实参,默认值
函数定义:
def describe_pet(pet_name,animal_type='dog'):
调用:
describe_pet('willie')
describe_pet(pet_name='willie')
describe_pet('harry','hamster')
describe_pet(pet_name='harry',animal_type='hamster')
describe_pet(animal_type='hamster',pet_name='harry')
3返回值
3.1 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
3.2实参可选:使用默认值
def get_formatted_name(first_name,last_name,middle_name=''):
"""返回整洁的姓名"""
if middle_name:
full_name = first_name + ' '+ middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi','hendrix')
print(musician)
musician = get_formatted_name('john','hooker','lee')
print(musician)
>>>Jimi Hendrix
>>>John Lee Hooker
实参middle_name指定一个默认值——空字符串。
3.3返回字典
def build_person(first_name,last_name,age=''):
"""返回一个字典,包含一个人的信息"""
person = {'first':first_name,'last':last_name}
if age:
person['age'] = age
return person
musician = build_person('jimi','hendrix',27)
print(musician)
>>>{'first': 'jimi', 'last': 'hendrix', 'age': 27}
函数接受简单的文本信息,将其放在一个更合适的数据结构中。
4传递列表
def greet_users(names):
for name in usernames:
msg = "Hello," + name.title() + "!"
print(msg)
usernames = ['hanna','jude','lily']
greet_users(usernames)
>>>Hello,Hanna!
>>>Hello,Jude!
>>>Hello,Lily!
4.1在函数中修改列表
列表传递给函数后,函数就可对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这能够高效地处理大量的数据。
unprinted_designs = ['iphone case','robot pendant','hellokity']
completed_models = []
while unprinted_designs:
current_design = unprinted_designs.pop()
print("Printing model: " + current_design)
completed_models.append(current_design)
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
>>>Printing model: hellokity
>>>Printing model: robot pendant
>>>Printing model: iphone case
>>>The following models have been printed:
>>>hellokity
>>>robot pendant
>>>iphone case
编写函数后:
def print_models(unprinted_designs,completed_models):
while unprinted_designs:
current_design = unprinted_designs.pop()
print("Printing model: " + current_design)
completed_models.append(current_design)
def show_completed_models(completed_models):
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
unprinted_designs = ['iphone case','robot pendant','hellokity']
completed_models = []
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)
>>>Printing model: hellokity
>>>Printing model: robot pendant
>>>Printing model: iphone case
>>>The following models have been printed:
>>>hellokity
>>>robot pendant
>>>iphone case
这个程序还演示了这样一种理念 : 即每个函数都应只负责一项具体的工作。第一个函数打印每个设计,而第二个显示打印好的模型;这优于使用一个函数来完成两项工作。编写函数时,如果发现它执行的任务太多,请尝试将这些代码划分到两个函数中。这有助于将复杂的任务划分成一系列的简单任务。
4.2禁止函数修改列表
当你不希望原始列表被改变的时候,可以向函数传递列表的副本:
function_name(list_name[:])
切片表示法 [ : ] 创建列表的副本。上例中,如果不想清空未打印的列表,可修改如下:
print_models(unprinted_designs[:],completed_models)
但除非特殊情况,最好还是将原始列表传递给函数:因为让函数使用现成列表可避免花时间和内存创建副本,从而提高效率,在处理大型列表时尤其如此。
5.传递任意数量的实参
def make_pizza(*toppings):
"""打印所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','cheese')
>>>('pepperoni',)
>>>('mushrooms', 'green peppers', 'cheese')
形参名*toppings 中的星号让Python创建一个名为toppings 的空元组,并将收到的所有值都封装到这个元组中。它以类似的方式处理不同的调用。Python将实参封装到一个元组中,不管多少个实参,即便函数只收到一个值也如此。
5.1结合使用:位置实参&任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
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','cheese')
>>>Making a 16-inch pizza with the following toppings:
>>>-pepperoni
>>>Making a 12-inch pizza with the following toppings:
>>>-mushrooms
>>>-green peppers
>>>-cheese
5.2使用任意数量的关键字实参
有时候需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键—值对,调用语句提供了多少就接受多少。
示例:创建用户简介,你知道你将收到有关用户的信息,但不确定会是什么样的信息。在下面的示例中,函数build_profile() 接受名和姓,同时还接受任意数量的关键字实参:
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='China',
field='physics')
print(user_profile)
>>>{'first name': 'albert', 'last name': 'einstein', 'location': 'China', 'field': 'physics'}
形参**user_info 中的两个星号让Python创建一个名为user_info 的空字典,并将收到的所有名称—值对都封装到这个字典中。在这个函数中,可以像访问其他字典那样访问user_info 中的名称—值对。
编写函数时,可以以各种方式混合使用位置实参、关键字实参和任意数量的实参。正确地使用这些类型的实参并知道它们的使用时机。知道在各种情况下哪种方法的效率是最高的。
6.函数编写
- 命名:应给函数或模块指定描述性名称,且只在其中使用小写字母和下划线。通俗易懂。
- 注释:每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面,并采用文档字符串格式。
- 给形参指定默认值时,等号两边不要有空格;
def function_name(parameter_0,parameter_1='default value'):
- 对于函数调用中的关键字实参,也遵循这种约定:
function_name(value_0,parameter_1='value')
- 形参过多情形:
def function_name(
parameter_0,parameter_1,parameter_2,
parameter_3,parameter_4,parameter_5):
function body...
- 如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开,
- 所有的import 语句都应放在文件开头,唯一例外的情形是:在文件开头使用了注释来描述整个程序。