目录
1、调用函数
要调用一个函数,需要知道函数的名称和参数。可以直接从Python的官方网站查看文档:
http://docs.python.org/3/library/functions.html#abs
2、定义函数
1、在Python中,定义一个函数要使用def
语句,依次写出函数名、括号、括号中的参数和冒号:
,然后,在缩进块中编写函数体,函数的返回值用return
语句返回。
def function_name(param1,param2,param3...):
statements
return / yield value 1,value2 #函数可以同时返回多个值,但其实就是一个tuple。
若把函数定义保存为a.py文件,可以在该文件的当前目录下启动Python解释器,用from a import function_name
来导入函数,注意 a
是文件名(不含.py
扩展名)
2、空函数 用pass语句
def nop():
pass
作用:pass
可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass
,让代码能运行起来
3、Python 函数的参数可以设定默认值,比如下面这样的写法:
def func(param = 0):
...
这样,在调用函数 func() 时,如果参数 param 没有传入,则参数默认为 0;而如果传入了参数 param,其就会覆盖默认值。
4、Python可以接受任何数据类型(整型,浮点,字符串等等),但是当传入了不恰当的参数时,会报错。python的内置函数会检查参数错误,但自定义函数不会,需要自己做参数检查。数据类型检查可以用内置函数 isinstance( ) 实现。如:
def my_abs(x):
if not isinstance(x, (int, float)): #只允许整数、浮点数类型的参数
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
5、import math语句表示导入math包,并允许后续代码引用math包里的sin、cos等函数。例如:
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
3、函数的参数
1、位置参数(必选参数)
def function_name(x) x即位置参数
2、默认参数
def function_name(x,n=2) n为默认参数,调用时只需要传入一个参数,若n!=2时,传入两个参数
设置默认参数需注意:
1、必选参数在前,默认参数在后,否则Python报错
2、变化大的参数在前,变化晓得参数在后。变化小的参数可以设置成默认参数。
3、不按顺序提供默认参数时,需要把参数名写上 参数名=...
优点:降低调用函数的难度
定义默认参数要牢记一点:默认参数必须指向不变对象! 例如:str、None
3、可变参数
即传入的参数个数可变,这些可变参数在函数调用时自动组装成一个tuple。
输入的参数个数可变,可以通过输入一个list或tuple达成,如调用函数calc:>>>calc([1.3.5])。若利用可变参数,可以简化为:>>>calc(1.3.5)
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
在定义一个可变参数后,若传入的是list或tuple,可以做如下处理:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
*number表示把nums
这个list的所有元素作为可变参数传进去
4、关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
表示方法:参数前面加两个*:**kw
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
输入参数时,可以只传入必选参数:name,age
关键字参数的作用:可以扩展函数的功能。比如,在person
函数里,我们保证能接收到name
和age
这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。
同可变参数一样,传入参数是一个dict时,可以**t处理,**dict表示把这个dict中所有的key-values用关键字参数传入到函数中。
5、命名关键字参数
即对关键字参数作限制,例如只接收city和job作为关键字:用法:*,隔开
def person(name, age, *, city, job):
print(name, age, city, job)
6、参数组合
参数的顺序为:必选参数—默认参数—可变参数—命名关键字参数—关键字参数
对于任意函数,都可以通过类似func(*args, **kw)
的形式调用它,无论它的参数是如何定义的。
4、递归函数
递归函数:在函数内部,调用函数本身,例如 求阶乘:
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
使用递归函数要防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
解决递归调用栈溢出的方法是通过尾递归优化
尾递归:在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。使递归本身无论调用多少次,都只占用一个栈帧,
def fact(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
递归函数要有递归的基础,递归的规律,并且通过分支结构(if...else...)把基础和规律分开:
递归基础的语句是要给个确定的结果。一般递归是n == 1 或者 n==0开始的。也就是if n == 1 : xxx 或者 if n==0: xxx 甚至有可能是if n== 0 or 1: xxx。有的递归可能有多个基础(比如斐波那契数列)
递归规律的语句要体现func(n)和func(n-1)的关系,也就是 else :yyy func(n-1) yyy。或者说,else语句要用到你定义的这个函数本身func(n-1)才能实现递归。(当然可能有时候不光要用n-1甚至还会用到n-2或者更多)