定义函数
>>> def greet_user():
... """显示简单的问候语"""
... print("Hello!")
...
>>> greet_user()
Hello!
函数内的文本称为文档字符串的注释,描述了函数是做什么的。文档字符串用三隐含括起来。Python使用它们来生成有关程序中函数的文档。
向函数传递信息
>>> def greet_user(username):
... """显示简单的问候语"""
... print(f"Hello, {username}")
...
>>> greet_user('Jesse')
Hello, Jesse
传递实参
1、位置实参
调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的shunxu.zhezhong关联方式称为位置实参。
>>> def describe_pet(animal_type,pet_name):
... """显示宠物的信息"""
... print(f"\nI have a {animal_type}.")
... print(f"My {animal_type}'s name is {pet_name.title()}.")
...
>>> describe_pet('hamster','harry')
I have a hamster.
My hamster's name is Harry.
2、关键字实参
>>> describe_pet(animal_type='hamster',pet_name='harry')
I have a hamster.
My hamster's name is Harry.
和下面的代码是一样的
>>> describe_pet(pet_name='harry',animal_type='hamster')
I have a hamster.
My hamster's name is Harry.
注意:使用关键字实参时,务必准确指定函数定义中的形参名。
默认值
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。
例如,如果你发现调用describe_pet()时,描述的大多是小狗,就可将形参animal_type的默认值设置为‘dog’。
>>> def describe_pet(pet_name,animal_type='dog'):
... """显示宠物的信息"""
... print(f"\nI have a {animal_type}.")
... print(f"My {animal_type}'s name is {pet_name.title()}")
...
>>> describe_pet(pet_name='willie')
I have a dog.
My dog's name is Willie
注意:使用默认值时,必须先在形参列表中列出没有默认值的形参,再列出有默认值的实参,这让Python依然能够正确地解读位置实参。
返回值
在函数中,可使用return语句将值返回到调用函数的代码行。返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。
>>> def get_formatted_name(first_name,last_name):
... full_name = f"{first_name} {last_name}"
... return full_name.title()
...
>>> musician = get_formatted_name('jimi','hendrix')
>>> print(musician)
Jimi Hendrix
让实参变成可选的
有时候,需要让实参变成可选的,这样使用函数的人就能只在必要时提供额外的信息。可使用默认值来让默认值来让实参变成可选的。
>>> def get_formatted_name(first_name,last_name,middle_name=''):
... """返回整洁的姓名"""
... if middle_name:
... full_name = f"{first_name} {middle_name} {last_name}"
... else:
... full_name = f"{first_name} {last_name}"
... return full_name.title()
...
>>> musician = get_formatted_name('jimi','hendrix')
>>> print(musician)
Jimi Hendrix
>>> musician = get_formatted_name('john','hooker','lee')
>>> print(musician)
John Lee Hooker
返回字典
函数可返回任何类型的值,保括列表和字典等较复杂的数据结构。
>>> 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'}
>>> def build_person(first_name,last_name,age=None):
... """返回一个字典,其中包含有关一个人的信息"""
... person = {'first':first_name,'last':last_name}
... if age:
... person['age']=age
... return person
...
>>> musician = build_person('jimi','hendrix',age=27)
>>> print(musician)
{'first': 'jimi', 'last': 'hendrix', 'age': 27}
结合使用函数和while循环
>>> def get_formatted_name(first_name,last_name):
... """返回整洁的姓名"""
... full_name = f"{first_name} {last_name}"
... return full_name.title()
...
>>> while True:
... print("\nPlease 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
... formatted_name = get_formatted_name(f_name,l_name)
... print(f"\nHello,{formatted_name}!")
...
Please tell me your name:
(Enter 'q' at any time to quit)
First_namehaha
Last_namehehe
Hello,Haha Hehe!
Please tell me your name:
(Enter 'q' at any time to quit)
First_nameq
传递列表
>>> def greet_users(names):
... """向列表中的每位用户发出简单的问候"""
... for name in names:
... msg = f"Hello,{name.title()}!"
... print(msg)
...
>>> usernames = ['hannah','ty','margot']
>>> greet_users(usernames)
Hello,Hannah!
Hello,Ty!
Hello,Margot!
在函数中修改列表
将列表传递给函数后,函数就可以对其进行修改。在函数中对这个列表所做的任何修改都是永久性地,折让你能够高效地处理大量数据。
这些是没有函数时的代码:
>>> #首先创建一个列表,其中包含一些要打印的设计
>>> unprinted_designs = ['phone case','robot pendant','dodecahedron']
>>> completed_models = []
>>> #模拟打印每个设计,直到没有未打印的设计为止
>>> #打印每个设计后,都将其移动列表completed_models中
>>> while unprinted_designs:
... current_design = unprinted_designs.pop()
... print(f"Printing model: {current_design}")
... completed_models.append(current_design)
...
Printing model: dodecahedron
Printing model: robot pendant
Printing model: phone case
>>> #显示打印好的所有模型
>>> print("\nThe following models have been printed:")
The following models have been printed:
>>> for completed_model in completed_models:
... print(completed_model)
...
dodecahedron
robot pendant
phone case
为重新组织这些代码,可编写两个函数,每个都做一件具体的工作。大部分代码与原来相同,只是效率更高。
>>> def print_models(unprinted_designs,completed_models):
... """
... 模拟打印每个设计,直到没有未打印的设计为止。
... 打印每个设计后,都将其移到列表completed_models中
... """
... while unprinted_designs:
... current_design = unprinted_designs.pop()
... print(f"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 = ['phone case','robot pendant','dodecahedron']
>>> completed_models = []
>>> print_models(unprinted_designs,completed_models)
Printing model: dodecahedron
Printing model: robot pendant
Printing model: phone case
>>> show_completed_models(completed_models)
The following models have been printed:
dodecahedron
robot pendant
phone case
禁止函数修改列表
有时候,需要禁止函数修改列表。
可以要将列表的副本传递给函数。
function_name(list_name[:])
传递任意数量的实参
>>> def make_pizza(*toppings):
... """打印顾客点的所有配料"""
... print(toppings)
...
>>> make_pizza('pepperoni')
('pepperoni',)
>>> make_pizza('mushrooms','green peppers','extra cheese')
('mushrooms', 'green peppers', 'extra cheese')
形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。
结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。
>>> def make_pizza(size,*toppings):
... """概述要制作的披萨。"""
... print(f"\nMaking a {size}-inch pizza with the following toppings:")
... for topping in toppings:
... print(f"-{topping}")
...
>>> make_pizza(16,'pepperoni')
Making a 16-inch pizza with the following toppings:
-pepperoni
>>> make_pizza(12,'mushrooms','green peppers','extra cheese')
Making a 12-inch pizza with the following toppings:
-mushrooms
-green peppers
-extra cheese
使用任意数量的关键字实参
有时候,需要接受任意数量的实参,但与小不知道传递给函数的会使什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键值对---调用语句提供了多少就接受多少。
>>> def build_profile(first,last,**user_info):
... """创建一个字典,其中包含我们直到的有关用户的一切"""
... user_info['first_name'] = first
... user_info['last_name'] = last
... return user_info
...
>>> user_profile = build_profile('albert','einstein',location = 'princeton',field = 'physics')
>>> print(user_profile)
{'location': 'princeton', 'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein'}
形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称对都放在这个字典中。
将函数存储在模块中
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 pizza
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
导入特定的函数
还可以导入模块中的特定函数,这种导入方法的语法如下:
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')
使用as给函数指定别名
如果要导入函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名:函数的另一个名称,类似于外号。要给函数取这种特殊的外号,需要在 导入它时指定。
from pizza import make_pizza as mp
mp(16,'pepperoni')
mp(12,'mushrooms','green peppers','extra cheese')
给模块指定别名的通用语法如下:
import module_name as mn
导入模块中的所有函数
使用*运算符可让python导入模块中的所有函数
from pizza import *
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers','extra cheese')