目录
1、位置实参
2、关键字实参
3、默认值
4、列表实参(传递原始列表)
5、使用切片传递列表副本实参
函数实参传递的方式有很多:位置实参(实参的顺序与形参顺序相同)、关键字实参(实参有变量名和值组成)、列表和字典。
位置实参:基于Python函数调用中的每个实参的顺序关联到函数定义中的一个形参。即实参按照顺序对应传递给相应的形参。
下边代码是一个宠物信息显示的函数,函数指出一个宠物属于哪种动物以及它叫什么名字:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 宠物信息显示函数
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', 'willie')
运行结果为:
I have a dog.
My dog's name is Willie.
上述代码中,实参‘dog’存储在形参animal_type中,实参‘Willie’存储在形参pet_name中。在函数体内使用这两个形参来显示宠物的信息。
位置实参调用函数时,实参的顺序非常重要,如果在运行中结果出乎意料,请检查函数调用中实参的顺序与函数定义中形参的顺序是否一致。
关键字实参:传递给函数的名称-值对,直接在实参中将名称和值关联起来。
还是上述宠物信息的例子,这里将使用关键字实参调用:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
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='willie', animal_type='dog')
运行结果与上述一样:
I have a dog.
My dog's name is Willie.
编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。
使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。
上述宠物信息例子,将形参animal_type的默认值设置为'dog' 。这样,调用describe_pet()来描述小狗时,就可不提供这种信息:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 注意提供默认值的形参要放在后边
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')
运行结果:
I have a dog.
My dog's name is Willie.
列表实参:传递列表名字。将列表传递给函数后,函数可对其进行修改,在函数中对这个列表所做的任何修改都是永久性的。
下边例子:一家为用户提交的设计制作3D打印模型的公司。需要打印的设计存储在一个列表中, 打印后移到另一个列表中。下面是在不使用函数的情况下模拟这个过程的代码:
# 首先创建一个列表,其中包含一些要打印的设计
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = [] # 空列表,存储已打印的设计
# 模拟打印每个设计, 直到没有未打印的设计为止
# 打印每个设计后, 都将其移到列表completed_models中
while unprinted_designs:
current_design = unprinted_designs.pop() # 未打印的设计从列表中删除(从末尾删除)
# 模拟根据设计制作3D打印模型的过程
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)
使用函数模拟这个过程的代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def print_models(unprinted_designs, completed_models):
"""模拟打印每个设计, 直到没有未打印的设计为止打印每个设计后, 都将其移到列表completed_models中"""
while unprinted_designs:
current_design = unprinted_designs.pop()
# 模拟根据设计制作3D打印模型的过程
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', 'dodecahedron'] # 未打印的设计列表
completed_models = [] # 用来存储打印的设计的列表
print_models(unprinted_designs, completed_models) # 调用打印设计的函数
show_completed_models(completed_models) # 调用显示打印的函数
上述未使用函数与使用函数运行结果均为:
Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case
The following models have been printed:
dodecahedron
robot pendant
iphone case
有时候,可能需要保留原始列表的内容,如上述代码,需要保留原来未打印设计的列表,但因为上述代码将所有未设计都移除了列表unprinted_designs,这个列表变成了空列表。
如果需要保留原始列表,则需要向函数传递列表的副本而不是原件。这样,函数所做的任何修改都只影响副本。
使用切片传递列表副本:function_name(list_name[:])(切片创建列表副本参考博文)
上述代码保留原始未打印设计的列表,可以如下调用(传递列表副本):
print_models(unprinted_designs[:], completed_models)
!!!注意:一般不要用此操作,因为让函数使用现成的列表可避免花时间和内存创建副本,从而提高效率。