此前提到的BIF就是Python帮助我们封装好的函数,可以直接使用。但有时候我们需要实现一些自定义的功能,这时就需要自己动手写函数。
简单来说,一个程序可以按照不同的功能实现,分割成许许多多的代码块,每一个代码块可以封装成一个函数。在Python中创建一个函数用def关键字:
注意,需要在函数名后加上一对小括号,这对小括号是必不可少的,因为有时候需要在这里放入参数,后面将会逐一介绍到,在这儿就不赘述了。
我们创建了一个函数,但是从来都不去调用它,那么这个函数里的代码就永远不会被执行。Python中调用一个函数也非常简单,直接写上函数名加上小括号即可:
这里简单说一下函数的调用和运行机制:
当函数myFirstFunction()发生调用操作的时候,Python会自动往上找到def myFirstFunction()的定义过程,然后依次执行该函数所包含的代码块部分(也就是冒号后边缩进部分的内容)。只需要一条语句,就可以轻松实现函数内的所有功能。
如果想把刚才的内容打印3次,只需要调用3次函数即可:
接下来就要讲讲刚才所说的小括号里的东西——函数的参数了。在函数刚开始发明出来的时候,是没有参数的,但有人提出了质疑:函数只不过是同样内容的代码进行打包,这样跟使用循环就没有什么本质不同了。所以,为了使每次调用的函数都有不同的实现,加入了函数的概念,参数使得函数可以实现个性化。
上述例子里有一个参数,在调用函数时,给出不同的参数值,就可以实现不同的输出。如果有多个参数,只需要用逗号隔开即可:
接下来,重点介绍一下几种参数。
函数从调用的角度来说,分为形式参数(parameter)和实际参数(argument),简称为形参和实参。跟绝大多数编程语言一样,形参指的是函数创建和定义过程中小括号里的参数,而实参则指的是函数在被调用过程中传递进来的参数。
对这个例子,mySecondFunction(name)中的name是形参,因为它只是代表一个位置、一个变量名;而调用时mySecondFunction(“小狗”)传递的"小狗"是实参,因为它是一个具体的内容,是赋值到变量名中的值。
普通的参数叫作位置参数,通常在调用一个函数的时候,稍有不注意就很容易搞乱位置参数的顺序,以至于函数无法按照预期来实现。因此,有了关键字参数。有了关键字参数,就可以很简单的解决这个潜在的问题。
关键字参数其实就是在传入实参时指定形参的变量名,当参数越来越多时,关键字参数起到的作用就越明显。
初学者很容易搞混关键字参数和默认参数,默认参数是在定义的时候赋予了默认值的参数:
使用默认参数的话,就可以不带参数去调用函数。所以,它们之间的区别是:
关键字参数是在函数调用的时候,通过函数名指定要赋值的参数,这样就不怕因为搞不清楚参数的顺序而导致函数调用出错;
而默认参数是在参数定义的过程中,为形参赋初始值,当函数调用的时候,不传递实参,则默认使用形参的初始值代替。
大多数时候他也称为可变参数。发明这种机制的动机是函数的作者有时候也不知道这个函数到底需要多少个参数。这时候,只需要在参数前边加上星号(*)即可。
看到上面这个例子也不难理解,Python就是把标志为收集参数的参数们打包成一个元组。
不过这里需要注意的是,如果在收集参数后边还需要指定其他参数,在调用函数的时候就应该使用关键字参数来指定,否则Python就会把你的实参都列入收集参数的范围。
所以,建议大家如果你的参数中带有收集参数,可以将其他参数设置为默认参数,这样不容易出错:
星号(*)其实既可以打包又可以“解包”。所谓“解包”,举个例子,如果你需要将一个列表a传入test的收集参数 *param中,那么调用test(a)时便会出错,此时需要在a前边加上个星号(*)表示实参需要“解包”后才能使用:
Python还有另一种收集方式,就是用两个星号(**)表示。跟前面的介绍不同,两个星号的收集参数表示将参数们打包成字典的形式。
收集参数其实有两种打包形式:一种是以元组的形式打包,另一种则是以字典的形式打包:
当参数带两个星号(**)时,传递给参数的任意个key=value实参会被打包进一个字典中。有打包就有解包:
有些时候,需要函数为我们返回一些数据来报告执行结果,所以我们的函数需要返回值。其实很简单,只需要在函数中使用关键字return,后面跟着的就是指定要返回的值。
在许多编程语言中,我们说一个函数是整型,意思是指这个函数会返回一个整型的返回值。而Python可以动态确定函数的类型,而且函数还能返回不同类型的值。就像以前提到的,Python没有变量,只有名字。此外,Python还可以同时返回多个值。
Python可以利用列表打包多种类型的值一次性返回。当然,也可以直接用元组的形式返回多个值:
给函数写文档是为了让别人可以更好的理解你的函数,所以这是一个好习惯,因此,适当的文档说明非常重要。而函数文档的作用是描述该函数的功能。
<1>函数文档字符串
我们看到,在函数开头写下的字符串是不会打印出来的,但是它会作为函数的一部分存储起来。这个称为函数文档字符串,它的功能跟注释是一样的。有人会说,既然一样,搞这么复杂干嘛?其实也不是完全一样:函数的文档字符串可以通过特殊属性_ _doc_ _获取(注意:两边分别是两条下划线)。
<2>help()函数
另外,想用一个函数确不确定其用法的时候,会通过help()函数来查看函数的文档。 因此,我们对自己的函数也可以依法炮制: