码迷,mamicode.com
首页 > 其他好文 > 详细

第 8 章 函数

时间:2017-03-30 00:06:37      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:ring   title   变量   组成   独立   des   doc   用户   接受   

    在本章中,我们将学习编写函数。函数是带名字的代码块,用于完成具体的工作。

    要执行函数定义的特定任务,可调用函数。需要在程序中多次执行同一项任务时,我们无需反复编写完成该任务的代码,而只需调用执行该任务的函数,让Python运行其中的代码。我们将发现,通过使用函数,程序的编写、阅读、测试和修复都将更容易。

    在本章中,我们还会学习向函数传递信息的方式。我们将学习如何编写主要任务是显示信息的函数,还有用于处理数据并返回一个或一组值的函数。最后,我们将学习如何将函数存储在被称为模块的独立文件中,让主程序文件的组织更为有序。

8.1  定义函数

    下面是一个打印问候语的简单函数,名为greet_user():

greeter.py
def greet_user():
#显示简单的问候语
print("Hello!")

greet_user()
这个示例演示了最简单的函数结构。代码行使用关键字def来告诉Python我们要定义一个函数。这是函数定义,向Python指出了函数名,还可能在括号
内指出函数为完成其任务需要什么样的消息。在这里,函数名为greet_user(),它不需要任何信息就能完成其工作,因此括号是空的(即便如此,括号也必不可
少)。最后,定义以冒号结尾。
紧跟在def greet_user():后面的所有缩进构成了函数体。上述的文本是被称为文档字符串(docstring)的注释,描述了函数是做什么的。文档字符串用三
引号扩起,Python使用它们来生成有关程序中函数的文档。
print("Hello!")是函数体内的唯一一行代码,greet_user()只做一项工作;打印Hello!。

8.1.1 向函数体传递信息

只要稍作修改,就可以让函数greet_user()不仅向用户显示Hello!,还将用户的名字用作抬头。为此,可在函数定义def greet_user()的括号内添加
username。通过在这里添加username,就可让函数接受我们给username制定的任何值。现在,这个函数要求我们滴啊用它给username指定一个值。调用greet
_user()时,可将一个名字传递给它,如下所示:
#定义一个函数带一个参数
def greet_user(username):
"""显示简单的问候语"""
print("Hello, " + username + ".")

greet_user("Zengmingzhu")
代码greet_user("Zengmingzhu")调用函数greet_user(),并向它提供执行print语句所需的信息。这个函数接受我们传递给它的名字,并向这个人发出
问候:
Hello, Zengmingzhu.
同样,greet_user(‘sarah‘)调用函数greet_user()并向它传递‘sarah‘,打印Hello,Sarah!.我们可以根据需要调用函数greet_user()任意次,调用时
无论传入什么样的名字,都会生成相应的输出。

8.1.2 实参和形参

前面定义函数greet_user()时,要求给变量username指定一个值。调用这个函数并提供这种信息(人名)时,它将打印相应的问候语。
在函数greet_user()的定义中,变量username是一个形参——函数完成其工作所需的一项信息。在代码greet_user(‘jesse‘)中,值‘jesse‘是一个实参
。实参是调用函数时传递给函数的信息。我们调用函数时,将要让函数使用的信息放在括号内。在greet_user(‘jesse‘)中,将实参‘jesse‘传递给了函数
greet_user(),这个值被存储在形参username中。

8.2 传递实参

鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多,可能用位置实参,这要求实参的顺序与形参的顺序
相同;也可使用关键字实参,其实每个实参都有变量名和值组成;还可使用列表和字典。

8.2.1 位置实参
我们调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式
被称为位置实参。
为明白其中的工作原理,来看一个显示宠物信息的函数。
#首先定义一个函数,然后调用这个函数
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(‘hamster‘,‘harry‘)
这个函数的定义表明,它需要一种动物类型和一个名字。调用describe_pet()时,需要按顺序提供一种动物类型和一个名字。例如,在前面的函数调用中
,实参‘hamster‘存储在形参animal_type中,而实参‘harry‘存储在形参pet_name中。在函数体内,使用了这两个形参来显示宠物的信息。
输出描述了一只名为Harry的仓鼠:
  I have a hamster.
  My hamster‘s name is Harry.
1、调用函数多次
我们可以根据需要调用函数任意次。要再描述一个宠物,只需再次调用describe_pet()即可:
#首先定义一个函数,然后调用这个函数
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(‘hamster‘,‘harry‘)
describe_pet("dog","willie")
第二次调用describe_pet()函数时,我们向它传递了实参‘dog‘和‘willie‘。与第一次调用时一样,Python将实参‘dog‘关联到形参animal_type,并将
实参‘willie‘关联到形参pet_name。与前面一样,这个函数完成其任务,但打印的是一条名为Willie的小狗的信息。至此,我们有一只名为Harry的仓鼠,还
有一只名为Willie的小狗:
I have a hamster.
My hamster‘s name is Harry.

I have a dog.
My dog‘s name is Willie.
调用函数多次是一种效率极高的工作方式。我们只需在函数中编写描述宠物的代码一次,然后每当需要描述新宠物时,都可调用这个函数,并向它提供新
宠物的信息。即便描述宠物的代码增加到了10行,我们依然只需使用一行调用函数的代码,就可描述一个新宠物。
在函数中,可根据需要使用任意数量的位置实参,Python将按顺序将函数调用中的实参关联到函数定义中相应的形参。

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(‘harry‘,‘hamster‘)
    在这个函数调用中,我们先制定名字,再指定动物类型。由于实参‘harry‘在前,这个值将存储到animal_type中;同理,‘hamster‘将存储到形参pet_nam
中。结果是我们得到了一个名为Hamster和Harry:
I have a harry.
My harry‘s name is Hamster.
如果结果像上面一样搞笑,请确认函数调用中实参的顺序与函数定义中形参的顺序一致。

8.2.2 关键字实参

关键字实参是传递给函数的名称-值对。我们直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆(不会得到名为Hamster的Harry这样
的结果).关键字实参让我们无须考虑函数调用中的实参顺序,还清楚地指出了函数调用中的各个值的用途。
下面来看重新编写pets.py,在其中使用关键字实参来调用describe_pet():
#定义一个函数,用户存储宠物的名字和类别
def describe_pets(animal_type,pet_name):
print("\nI have a " + animal_type.title() + ".")
print("My pet " + animal_type.title() + "‘s name is " + pet_name.title() +".")

describe_pets(pet_name = ‘harry‘,animal_type = ‘hamster‘)
函数describe_pet()还是原来那样,但调用这个函数时,我们向Python明确地指出了各个实参对应的形参。看到这个函数调用时,Python知道应将实参
‘hamster‘和‘harry‘分别存储在形参animal_type和pet_name中。输出正确无误,它指出我们有一只名为Harry的仓鼠。

8.2.3 默认值

编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用制定的实参值;否则,将使用形参的默认值。因此,给形参指定
默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。
例如,如果我们发现调用describe_pet()时,描述的大都是小狗,就可将形参animal_type的默认值设置为‘dog‘。这样,调用describe_pet()来描述小
狗时,就可不提供这种信息:
def describe_pet(pet_name,animal_type = ‘dog‘):
print(‘\nI have a ‘ + animal_type.title() + ‘.‘)
print("My " + animal_type + "‘s name is " + pet_name + ".")

describe_pet("Harry")
这里修改了函数describe_pet()的定义,在其中给形参animal_type制定了默认值‘dog‘.这样,调用这个函数时,如果没有给animal_type指定值,
Python将把这个形参设置为‘dog‘.
I have a Dog.
My dog‘s name is Harry.
请注意,在这个函数中,修改了形参的排列顺序。由于给animal_type指定了默认值,无需通过实参来指定动物类型,因此在函数调用中只包含一个实参
——宠物的名字。然而,Python依然将这个实参视为位置实参,因此,如果函数调用中只包含宠物的名字,这个实参将关联到函数定义的第一个形参。这就是需
要将pet_name放在形参列表开头的原因所在。
现在,使用这个函数的最简单的方式是,在函数调用中只提供小狗的名字:
describe_pet("willie")
这个函数调用的输出与前一个示例相同。只提供了一个实参——‘Willie’,这个实参将关联到函数定义中的第一个形参——pet_name。由于没有给anima
l_type提供实参,因此Python使用其默认值‘dog‘.
如果要描述的动物不是小狗,可使用类似于下面的函数说明:
def describe_pet(pet_name,animal_type = ‘dog‘):
print(‘\nI have a ‘ + animal_type.title() + ‘.‘)
print("My " + animal_type + "‘s name is " + pet_name + ".")

describe_pet(animal_type = "haster",pet_name = "Harry")
describe_pet(pet_name = "Harry",animal_type = "Haster")
由于显式地给animal_type提供了实参,因此Python将忽略这个形参的默认值。
注意 使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。这让Python依然能够正确地解读位置实参。



 
 





 

第 8 章 函数

标签:ring   title   变量   组成   独立   des   doc   用户   接受   

原文地址:http://www.cnblogs.com/gengcx/p/6642443.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!