一、实参和形参
def greet_user(username):
print("Hello,"+username.title()+"!")
greet_user('jesse')
在上面这个例子中,greet_user(username)中的username变量就是形参,形参就是函数完成其工作时所需要的一项信息。下面函数调用greet_user('jesse')中的‘jesse'就是实参,实参是调用函数时传递给函数的信息。
在greet_user('jesse')中将’jesse'传递给函数greet_user(),这个值被存储在形参username中。
二、传递实参
2.1位置实参
调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。
def describe_pet(animal_type,pet_name):
print(" I have a "+animal_type+".")
print("My"+animal_type+"'s name is"+pet_name.title())
describe_pet('hamster','harry')
运行结果:
位置实参的顺序很重要,必须一一对应。
2.2 关键字实参
关键字实参是传递给函数的名称-值对。你直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆。关键字实参让你无需考虑函数中实参顺序,还清楚的指出了函数调用中各个值得用途。
还是describe_pet()函数,调用方式改成describe_pet(animal_type='hamster',pet_name='harry')。
2.3 默认值
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参,否则将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。
def describe_pet(animal_type,pet_name='harry'):
print(" I have a "+animal_type+".")
print("My"+animal_type+"'s name is"+pet_name.title())
describe_pet('hamster')
在以上的函数调用中,只提供一个实参,它会自动对应到第一个形参,也就是说Python依旧将这个实参当作位置实参。所以,使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。
在某些情况下可以使用默认值让实参变成可选的。
比如下面的函数定义:
def get_formatted_name(first_name,last_name,middle_name=''):
为了将中间名变成可选的,将其移到形参列表结尾,并设置其值为空字符串。这样在传递实参时可以选择性传middle_name。
2.4等效的函数调用
鉴于可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式。
def describe_pet(pet_name,animal_type=’dog'):
基于这种定义,在任何情况下都必须给pet_name提供参数;指定该实参时可以使用位置方式,也可以使用关键字方式。如果要描述的动物不是小狗,还必须在函数调用中给animal_type提供实参;同样,指定该实参时可以使用位置方式,也可以使用关键字方式。
下面对这个函数的调用都可以:
describe_pet('willie') #默认值和位置实参
describe_pet(pet_name='willie') #默认值和关键字实参
describe_pet('harry','hamster') #位置实参,忽略默认值
describe_pet(pet_name='harry',animal_type='hamster') #关键字实参,忽略默认值
2.5传递列表
传递列表只是将列表作为实参传递给函数,要注意一下几点:
(1)将列表作为实参传递给函数之后,函数就可以对其进行修改。在函数中对这个列表所做的任何修改都是永久性的,这让你能够搞笑的处理大量的数据。
(2)如果需要禁止函数修改列表,可以向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而不影响原件。可用列表切片[:]创建列表副本(这个上篇博客有说)。
(3)虽然向函数传递列表副本可保留原始列表的内容,但除非有充分的理由需要传递副本,否则还是应该将原始列表传递给函数,因为让函数使用现成列表可避免花时间和内存创建副本,从而提高效率,在处理大型列表时更应该如此。
2.6传递任意数量的实参
def make_pizza(*toppings):
print(toppings)
形参名*topping中的*号让Python创建一个名为topping的空元组,并将所有收到的值都封装在这个元组中。
函数调用:
make_pizza(‘pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
运行结果:
注意:如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
示例:
运行结果:
2.7传递任意数量的关键字实参
有时候需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。可将函数编写成能够接受任意数量的键值对。
def build_profile(first,last,**user_info):
形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称-值对都封装到这个字典中。在这个函数中,可以像访问其他字典那样访问user_info中的名称-值对。