函数是有名称的代码块,用于完成具体工作。要执行函数定义的特定任务,需要调用该函数。
需要在程序中多次执行同一项任务时,无须反复编写同一代码块,只需要调用执行该任务的函数。
1. 定义函数
def greet_user(): # 此为最简单的示例,该函数名为greet_user,不需要传递参数运行,()内为空但不可以省略,定义语句以 : 结尾。
print("Hellow,dear user!") #该函数实现输出简单的问候语。
greet_user() # 调用并执行函数。同上该函数没有必须传递的参数,所以()内为空,但不可以省略
Hellow,dear user!
2. 向函数传递信息(参数)
def greet_user2(username): #定义函数,并定义需要传递的参数
print(f"hellow, {username}!")
greet_user2('Kong Zi')#调用函数并传递参数
hellow, Kong Zi!
3. 实参和形参
形参:在函数greet_user2定义中,变量username是一个形参(parameter),即函数完成工作所欲要的信息。
实参:在代码greet_user2('孔子')中,值'kong zi '是实参(argument),即调用函数时传递给函数的信息。
3.1 传递实参
函数定义中可以包含多个形参,因此函数调用中也可能包含多个实参。
向函数传递参数的方式:
(1)位置实参:要求实参的顺序与形参相同。
(2)关键字实参:由变量名和值组成。此外,还可以使用字典和列表。
def describe_food(food_type,food_weight,food_manufacture_date):
print(f"We will eat {food_type} at lunch.")
print(f"We have {food_weight}g {food_type} .")
print(f"The {food_type} manufacture is {food_manufacture_date}".)
describe_food('beef','1000','20220407')
We will eat beef at lunch.
We have 1000g beef .
The beef manufacture is 20220407.
3.2 位置实参顺序非常重要,如果实参的顺序不正确,将会出现意料之外的结果。
describe_food('beef','20220408','1000')
We will eat beef at lunch.
We have 20220408g beef .
The beef manufacture is 1000.
3.3 关键字实参
关键字实参是传递给函数的名称值对。因为在传递过程中直接将实参名称和值关联起来,所以不会混淆。
关键字实参无需考虑实参的顺序,还清楚的指出了各实参的用途。
def describe_rock(rock_designation,rock_color,rock_composition):
print(f"The name of the rock is {rock_designation}.")
print(f"The color of the rock is {rock_color}.")
print(f"The composition of the rock is {rock_composition}.")
describe_rock(rock_designation='sandrock',rock_color='red',rock_composition='quartz')
The name of the rock is sandrock.
The color of the rock is red.
The composition of the rock is quartz.
3.4 默认值
编写函数时可以给每个形参指定默认值。在调用函数传递实参时,python将使用指定实参值。
否则,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。
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('gang ben') #传递一个实参,将值传递给第一个形参。
describe_pet('mao qiu','cat') #等效的函数调用。传递实参时,可以采用位置方式、关键字方式。
describe_pet(pet_name='manman',animal_type='tutle') #传递两个实参,指定形参名进行传递。推荐用该语句传递实参。
describe_pet(animal_type= 'hamster',pet_name= 'jack') #采用关键字方式,参数的位置可以打乱。
I have a dog.
My dog's name is Gang Ben
I have a cat.
My cat's name is Mao Qiu
I have a tutle.
My tutle's name is Manman
3.5 避免实参错误
调用函数时,如果出现实参不批欸的错误,说明你提供的实参多余或少于函数完成工作需要的信息。
def describe_rock1(rock_designation,rock_color,rock_composition):
print(f"The designation of the rock is {rock_designation} ,"
f"\nthe color is {rock_color},and the main composition is quartz")
describe_rock1() #不传递参数将引起错误。
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3361, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-18-3dab8dbdc155>", line 6, in <cell line: 6>
describe_rock1() #不传递参数将引起错误。
TypeError: describe_rock1() missing 3 required positional arguments: 'rock_designation', 'rock_color', and 'rock_compsition'
4. 返回值
函数并非总是直接显示输出,他还可以处理一些数据,斌返回一个或一组数值。返回的值称返回值。
在函数中可以使用return语句将值返回到调用函数的代码行。返回值让你能够将程序的大部分繁重的工作交由函数完成,简化主程序。
返回简单值
def get_formatted_name(first_name,last_name):
full_name = f"{last_name} {first_name}"
return full_name.title()
poet = get_formatted_name('bai','li')
print(poet)
Li Bai
5.设置可选择赋值的实参
def get_formatted_name1(first_name,middle_name,last_name):
full_name = f"{last_name} {middle_name} {first_name}"
return full_name.title()
poet = get_formatted_name1('bai','','li')
print(poet)
Li Bai
以上函数需要同时传递名、中间名和姓 才能正确运行,如果只传递名和姓,将不能正确运行。
但并不是所有的人都有中间名,为了将 middle_name 变成可选择赋值的形参,可以预先指定空的默认值。
这样,用户没有中间名时就可以不传递该参数。
对代码进行优化,以适应传递3个实参和2个实参的情况。
def get_formatted_name2(last_name,first_name,middle_name=''): #将中间名设置为最后一个形参,默认值为空字符串
if middle_name:
full_name = f"{last_name} {middle_name} {first_name}"
else:
full_name = f"{last_name} {first_name}"
return full_name.title()
poet = get_formatted_name2('du','fu')
print(poet)
poet = get_formatted_name2('meng','ran','hao')
print(poet)
Du Fu
Meng Hao Ran
以上函数需要同时传递名、中间名和姓 才能正确运行,如果只传递名和姓,将不能正确运行。
但实际情况是:并不是所有的人都有中间名,为了将 middle_name 变成可选择赋值的形参,可以预先指定空的默认值。
之后,用户没有中间名时就可以不传递该参数。
def get_formatted_name2(last_name,first_name,middle_name=''): #将中间名设置为最后一个形参,默认值为空字符串
if middle_name:
full_name = f"{last_name} {middle_name} {first_name}"
else:
full_name = f"{last_name} {first_name}"
return full_name.title()
poet = get_formatted_name2('du','fu')
print(poet)
poet = get_formatted_name2('meng','ran','hao')
print(poet)
Du Fu
Meng Hao Ran