Python不但能非常灵活地定义函数,而且本身内置了很多有用的函数,可以直接调用。
在上面的网站上我们可以进行查询,Python具体都有哪些函数。
我们也可以再交互命令行中来查找函数:
>>> help (abs) Help on built-in function abs in module builtins: abs(x, /) Return the absolute value of the argument.
help(函数名)是一个能够在交互命令行中查找函数功能的语句。
这个abs是一个取绝对值得函数,我们这里还有比较函数:cmp(这里需要注意的是在3.0版本当中已经不存在cmp这个函数了,它已经被比如__lt__(),__eq__()等。如果需要使用cmp(),可以使用(a>b)-(a<b)替代。)
还有转换函数int(),以及str()等
虽然我们有很多已经被定义的函数,但同时我们也可以自己定义函数:
在Python中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回
>>> def my_abs(x): if x >= 0: return x else: return -x
函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。
如果没有return语句,函数执行完毕后也会返回结果,只是结果为 None。
在使用函数的时候我们会遇到返回多值的情况:
>>> import math >>> def move(x,y,step,angle): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx,ny >>> x,y = move(100,100,60,math.pi/6) >>> print (x,y) 151.96152422706632 70.0 >>> r = move(100,100,60,math.pi/6) >>> print (r) (151.96152422706632, 70.0)
但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
上面叙述了一个简单的函数的定义,在这这里我们还需要介绍一种函数:递归函数
一个函数在自己内部反复的调用者自己就叫做递归函数。
我们这里用一个介绍阶层函数举例:fact(n)
>>> def fact(n): if n == 1: return 1 return n * fact(n-1) >>> fact(1) 1 >>> fact(5) 120 >>> fact(10) 3628800
在这里就是用了递归函数,在一个函数当中包含它们自己。
在下面我们会展示一下递归函数的调用方式:
1 2 3 4 5 6 7 8 9 10 |
|
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试计算 fact(10000)。
在这里我们以简单的汉诺塔举例:
>>> def move(n,a,b,c): if n==1: print (a,‘-->‘,c) return else: if n >= 2: move(n-1,a,c,b) print(a,‘-->‘,c) move(n-1,b,a,c) >>> move(2,‘A‘,‘B‘,‘C‘) A --> B A --> C B --> C
定义函数的时候,还可以有默认参数。
例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数:
>>> int (‘123‘) 123 >>> int (‘123‘,8) 83
这里如果我们不添加后面的数字的话我们电脑就默认是转化为10进制,而如果我们添加后面呃数字的还额外我们就可以定义函数的转化方式。
函数的默认参数的作用是简化调用,你只需要把必须的参数传进去。但是在需要的时候,又可以传入额外的参数来覆盖默认参数值。
由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面
如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数 :
>>> def f(*args): print (args) >>> f() () >>> f(‘a‘) (‘a‘,) >>> f(‘a‘,‘b‘) (‘a‘, ‘b‘)
在这里args可以被看成一个tuple,因为它的输出是一个tuple。
定义可变参数的目的也是为了简化调用。