目录
1. 定义函数
1.1 向函数传递信息
1.2 形参和实参
2. 传递实参的方式
2.1 位置实参
2.1.1 多次调用函数
2.1.2 顺序的重要性
2.2 关键字实参
2.3 默认值
2.4 避免实参错误
3. 返回值
3.1 让实参变为可选
3.2 返回字典
3.3 结合使用while
4. 传递列表
5. 传递任意数量实参
5.1 任意数量实参
5.2 结合位置实参和任意数量实参
5.3 使用任意数量的关键字实参
6. 将函数存储在模块中
6.1 导入整个模块
6.2 导入特定函数
6.3 使用as给函数指定别名
6.4 使用as给模块指定别名
6.5 导入模块中所有函数
7. 默认规则
1. 定义函数
除了之前提到过的python内自带的函数,例如input()、sorted()、range()等,用户还可利用关键字def自行定义函数方法,以便重复调用。例如:
def greet_user()
"""显示简单的问候语"""
print("Hello!")
greet_user()
首行代码进行了函数定义,def指出了函数名,还可在括号内指出函数为完成其任务需要什么样的信息,括号也可为空;第二行语句为文档字符串,用三引号括起;后续代码指明了所定义函数所要执行的操作。
1.1 向函数传递信息
在括号中添加一个变量名,可通过该变量名向所定义的函数传递一些信息。
def greet_user(username)
"""显示简单的问候语"""
print("Hello!"+username.title()+"!")
greet_user('hysen')
上述代码中将hysen传递给username变量,并在greet_name()函数中得以调用。
1.2 形参和实参
在上述代码中,username与用户输入的‘hysen’互为形参与实参。实参是调用函数时传递给函数的信息,这个值被存储在形参之中,可以理解为形参为实参向函数传递信息的中介。
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('dog','xueli')
在上述代码的函数调用中,用户输入的实参‘dog’与‘xueli’按照定义函数时的顺序依次赋值给形参animal_type与pet_name。
2.1.1 多次调用函数
如若需要多次调用函数,只需重新给函数赋值实参即可,python将会自动给形参赋值新对应的形参。注:每次调用函数都会执行,并输出相对应的结果,不同的调用之间不会影响相互的输出结果。
在函数中,可根据需要使用任意数量的位置实参,python将按顺序将函数中调用的实参与形参一一对应。
2.1.2 顺序的重要性
使用位置实参来调用函数时,如果实参的输入顺序有误,则会直接导致对应的形参得不到想要的赋值,进而使得调用函数的输出结果有误。
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(pet_name='xueli',animal_type='dog')
在调用函数时就将形参与实参进行了明确的匹配,无需考虑实参与形参的匹配了。
2.3 默认值
在定义函数时,可在设定形参时直接给其赋值,这样这个形参就有了默认值(初始值),此时即使在调用函数时不给对应形参赋值实参,函数也会将默认值作为结果输出。
但是需要注意的是,若在调用实参时不使用关键字实参类型,仅仅输入实参的值,则python会默认为是位置实参方式,可能会将某些已经赋默认值的形参重新赋值,因此在使用默认值时,要注意实参的输入顺序,或者使用关键字实参方式来传递实参。为防止上述情况,可在形参列表中先列出没有默认值的形参,再列出有默认值的形参。位置实参、关键字实参、默认值这几种方法可混合使用,相互之间并没有冲突的关系,只要函数调用能生成你希望的输出就行。
2.4 避免实参错误
在使用函数时,若用户提供的实参多于或少于函数工作所需的信息时,python将会报错,提示实参不匹配错误。
3. 返回值
函数并非总是直接显示输出,它还可以处理一些数据,并返回一个或一组值。在调用返回值的函数时,需要提供一个变量,用于存储返回的值。
3.1 让实参变为可选
之前提到,当提供的实参数量与函数运行所需的信息不匹配时,函数将会无法运行。我们可以将部分实参变成可选的,使得只在需要的时候才调用某些实参,例:
def get_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()
musican=get_name('xxx','sss')
print(musican)
musican=get_name('xxx','sss','qqq')
print(musican)
在上述代码段中,首先给middle_name赋值了一个空字符串,并利用if语句在代码段中判断middle_name是否在实参中有输入,并根据结果输出相对应的full_name,将得到的full_name值用return返回给函数get_name,在调用函数get_name时用变量musican存储所得结果。需要注意的是,用if判定时,判定的是布尔类型变量,当middle_name中为默认值空字符串时,其判定布尔变量为“False”;若实参中对middle_name有输入,middle_name的布尔类型为“True”。
3.2 返回字典
函数可返回任意类型的值,包括列表和字典类型的数据结构。例:
def build_person(first_name,last_name,age=""):
person={'first':first_name,'last':last_name}
if age:
person['age']=age
return person
musican= build_person('jimi','white',age=27)
print(musican)
musican= build_person('jimi','white')
print(musican)
函数定义中,age是可选形参,其默认值为空字符,只有当age有输入时,字典person中才会加入age键与对应值。
3.3 结合使用while
def get_name(first_name,last_name,middle_name=""):
full_name = 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
for_name=get_name(f_name,l_name)
print('nhello,'+for_name)
将实参调用与while相结合,用变量作为实参输入,并利用while进行循环判定。
4. 传递列表
在调用函数输入实参时,可如同上述代码段中利用变量传输值一样,将实参用列表名代替,这样可将一个列表传递给函数,之后在函数中利用循环代码段,将列表中的元素进行逐一使用。
可定义多个函数代码段,将一个函数的功能分割为多块代码。
练习8-11:
magic_name=['aaa','bbb','ccc']
new_name=[]
def make_great(name):
for magic in name:
magic = magic+" the Great"
new_name.append(magic)
return new_name
def show_magic(name):
for magic in name:
print(magic)
make_great(magic_name)
show_magic(new_name)
print(magic_name)
print(new_name)
5. 传递任意数量实参
5.1 任意数量实参
当不知道要接收多少个实参而只有一个形参时,可用“*”对形参名进行修饰,“*”可创建一个空元组,并将收到的所有值都封装在这个元组之中。例:
def make_pizza(*topping):
print(topping)
make_pizza('aaa')
make_pizza('aaa','sss','www')
5.2 结合位置实参和任意数量实参
如要函数接收不同类型的实参,要在函数定义时在括号中将接收任意数量实参的形参放在最后。python将前面的实参按照位置顺序赋值给对应的形参,再将剩下的实参都收集在最后的形参元组中。
5.3 使用任意数量的关键字实参
任意数量实参可升级使用,通过使用两个星号“**”,可将形参变为一个空字典。例:
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('aaa','bbb',xxx='sss',kkk='qqqq')
print(user_profile)
“user_info”前面的两个星号**使得python构建了一个“user_info”的空字典,并将后续收到的所有键-值对封装到字典中。
6. 将函数存储在模块中
通过将函数存储在独立的文件中形成模块,再将模块导入到主程序中,可隐藏代码细节,减轻程序的解读复杂度,并有利于单独修改函数功能。使用import语句使用模块中的代码。
6.1 导入整个模块
模块是扩展名为.py的文件,包含要导入到程序中的代码。
模块:pizza.py
def make_pizza(*topping):
print(topping)
调用:
import pizza
pizza.make_pizza('aaa','bbb','sssss')
python读取文件时,代码行import pizza让python打开文件pizza.py,并将其中的所有函数都复制到这个程序中。调用函数时,语句格式如下:模块名.函数名(实参)
6.2 导入特定函数
如果并不打算调用整个模块,只需调用模块中的部分函数。语句格式如下:
from 模块名 import 函数名1,函数名2,函数名3
6.3 使用as给函数指定别名
若要导入的函数名称与现有程序中函数名称冲突,可在本程序中使用as为其指定别名,且需要在导入该函数时完成操作。例:
from pizza import make_pizza as mp
mp('aaa','bbb','sssss')
语句格式如下:from 模块名 import 函数名 as 别名
6.4 使用as给模块指定别名
当需要给模块指定别名时,如模块名过长的情况,与给函数指定别名用法相似。例:
from pizza as p
p.make_pizza('aaa','bbb','sssss')
语句格式如下:from 模块名 as 别名
6.5 导入模块中所有函数
语句格式如下:from 模块名 import * 可导入某模块中所有函数
需要注意的是,这种方法的作用与直接调用整个模块无异,但采用这种方法调用全部函数时,python可能遇到多个名称相同的函数或者变量,进而覆盖函数。
7. 默认规则
①. 编写函数时,应当给函数指定一个描述性的名称,且只采用小写字母和下划线,便于解读代码。在命名模块时也应遵守相同规则;
②. 给形参指定默认值时,等号两侧不要有空格;在使用关键字实参时,也应遵守相同规则;
③. 程序中包含多个函数时,不同函数之间可加入空行,以便区分。



