什么是函数?函数是带名字的代码块,用于完成具体的工作。
要执行函数定义的特定任务,可调用该函数。需要在程序中多次执行同一项任务时,无需反复编写完成该任务的代码,只需调用执行该任务的函数。
下面定义一个简单的函数。
def say_hello():
"""打印Hello"""
print "hello".title()
say_hello()
结果
Hello
这演示了一个最简单的函数结构。在第一行的代码中,使用了关键def来告诉Python要定义一个函数。这是一个函数定义,并向Python指出了函数名,还可能在括号内指出函数为完成其任务需要什么样的信息。在这段代码中,函数名为say_hello(),它不需要任何信息就能完成其任务,因此括号是空的,即使如此,括号也是不可缺少的。最后,定义以冒号结尾。
紧跟在def say_hello():后面所有缩进行构成了函数体。第二行文本被称为文档字符串的注释,也就是每种编程语言的注释。它描述了函数是做什么的。文档字符串用三个引号括起。
该函数内只有一行Python代码,就是打印字符串hello并首字母大写。
要使用这个函数,可直接调用它。函数调用让Python执行函数的代码。要调用函数,可依次指定函数名以及括号括起的必要信息。如上述第4行代码,由于定义的函数不需要任何的信息,因此调用的时候只输入say_hello()即可。也就相当于每次调用函数say_hello(),都执行一次定义在函数say_hello()内部的代码块。
改造一下上面的代码
def say_hello(name):
"""打印Hello"""
print "hello".title() + " " + name.title() + "!"
say_hello('dana')
结果
Hello Dana!
在定义函数say_hello的括号里面添加了name,在调用的时候传入了字符串dana.可以发现,哎呦,传入的字符串dana被打印了出来。在定义函数的时候,添加在括号里面的name是一个变量,在调用的时候,放入真正想要放入 的数据。函数体就处理了该数据。
可以根据需要调用函数say_hello()任意次,调用时无论什么名字,都形成了响应的输出。
在函数say_hello()的定义中,变量name是一个形参,函数完成其工作所需的一项信息。在代码say_hello(‘dana’)中,值’dana’是一个实参。实参是调用函数时传递给函数的信息。调用函数时,将要让函数使用的信息放在括号内。在say_hello(‘dana’)中,将实参’dana’传递给了函数say_hello(),这个值被存储在形参name中。
函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同。也可使用关键字实参,其中每个实参都由变量名和值组成。还可使用列表和字典。
调用参数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。
def say_hello(name,fruit):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello('dana','apple')
结果
Hello Dana!
You like fruit is apple
这个函数接收两个参数,第一个变量为name,第二个变量为fruit。在调用函数的时候,第一个实参为’dana’,第二个实参为’apple’。从而函数打印了两句话。
可以根据需要调用函数任意次,这里再调用一次。
def say_hello(name,fruit):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello('dana','apple')
say_hello('david','orange')
结果
Hello Dana!
You like fruit is apple
Hello David!
You like fruit is orange
调用函数多次是一种效率极高的工作方式。只需要编写谁喜欢吃什么水果,就会直接打印出来,即便是函数中的代码增加了,改动了,也不需要改动调用函数的位置。简直爽歪歪!
在函数中,可根据需要使用任意数量的位置实参,Python将按顺序将函数调用中的实参关联到函数定义中相应的形参。
在使用位置实参来调用的调用函数时,如果实参的位置不会,函数也是可以正常执行的。
def say_hello(name,fruit):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello('apple','dana')
say_hello('orange','david')
结果
Hello Apple!
You like fruit is dana
Hello Orange!
You like fruit is david
在函数中,先指定了爱吃的水果的名称,后指定名字。可以看到执行的结果如上。然而程序并没有报错。在写代码的过程中,有时候不小心就会犯这种错误,而且这种错误还是不容易发现的。
关键字实参是传递给函数的名称-值对。直接在实参中将名称和值关联起来,因此向函数传递实参时不会混淆。关键字实参无需考虑函数调用中实参的顺序,还清楚的指出了函数调用中各个值的用途。
def say_hello(name,fruit):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello(fruit='apple',name='dana')
say_hello(fruit='orange',name='david')
结果
Hello Dana!
You like fruit is apple
Hello David!
You like fruit is orange
可以看到,在代码中,参数的位置并不对应,但是通过指定关键字,可以与函数中的形参一一对应。
关键字实参的顺序无关紧要,因为Python知道各个值应该存储到哪个形参中。
使用关键字实参时,务必准确的指出函数定义中的形参名。
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参值。否则,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。
def say_hello(name,fruit = 'apple'):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello('dana')
say_hello('david','orange')
结果
Hello Dana!
You like fruit is apple
Hello David!
You like fruit is orange
可以看到,在第一次调用函数的时候,没有指定水果的名称。使用了函数的默认值。在第二次调用时,指定了水果的名称,所以使用了指定的水果名称。这就是默认值的作用,不指定,就用默认的。
需要特别注意的一点,使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参。这才能让Python能正确的解读位置实参。
开始使用函数后,经常会遇到实参不匹配的情况。就和我一样。哈哈。不过这没有关系。因为它会给我们抛出错误。
def say_hello(name, fruit='apple'):
print "hello".title() + " " + name.title() + "!"
print "You like fruit is " + fruit
say_hello()
结果
Traceback (most recent call last):
File "function.py", line 8, in <module>
say_hello()
TypeError: say_hello() takes at least 1 argument (0 given)
Python会告诉这是错误的。并指出函数say_hello()需要至少一个参数,但是在调用的时候一个都没有给它。
有时候函数接收很多的参数,在调用的时候务必要对应好。避免不必要的错误。
在编程中,错误是不可避免的,只要在调试的过程中调整过来就可以了。所以报错大可不必恼火,这是在正常不过的了。
希望小伙伴们都少一些bug。