一、调用内置函数
- 官方文档查看函数
http://docs.python.org/3/library/functions.html#abs
二、自定义函数
- 定义一个函数
def my_abs(x):if x >= 0:return xelse:return -x#调用my_abs(12)
- 参数检查
- 数据类型检查可以用内置函数isinstance()实现:
def my_abs(x):if not isinstance(x, (int, float)):raise TypeError('bad operand type')if x >= 0:return xelse:return -x
- 默认参数
- 注意:默认参数必须指向不变对象!
def power(x, n=2):s = 1while n > 0:n = n - 1s = s * xreturn s#调用时power(2) #实际是调用power(2,2)
- 可变参数
# 可变参数#定义可变参数需要在参数前加*符号def calc(*numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum#已经有一个list或者tuple,要调用一个可变参数a=[1,2,3]#方法一,可以单独取出list或tuple中的元素传入calc(a[0],a[1],a[2])#方法二 在变量前加符号*; *a表示把a这个list的所有元素作为可变参数传进去。calc(*a)
- 关键字参数
- 关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
- 关键字参数,它可以扩展函数的功能
# 关键字参数def person(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw)person("张三", 18, weight=40)#先组装好一个dict;当作关键字参数传入extra = {'city': 'Beijing', 'job': 'Engineer'}#可以一个个单独传入person('Jack', 24, city=extra['city'], job=extra['job'])#也可以使用**符号标志位关键参数传入; **extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意# kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。person('Jack', 24, **extra)
- 命名关键参数
- 命名关键字参数必须传入参数名
- 命名关键字参数可以有缺省值
- 用于限制用户输入的关键参数
# 命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。def person(name, age, *, city, job):print(name, age, city, job)# 已经有了可变参数,那么后边的参数会被识别为命名关键参数;不需要再使用特殊分隔符*标识def person(name, age, *args, city, job):print(name, age, city, job)# 调用person("abc",20,city="123",job="123")
- 参数组合
- 参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
三、递归函数
- 简单的递归函数;计算阶乘
def fact(n):if n == 1:return 1return n * fact(n - 1)
- 解决递归调用栈溢出的方法是通过尾递归优化; 主要是要把每一步的乘积传入到递归函数中:
def fact_iter(num, product=1):if num == 1:return productreturn fact_iter(num - 1, num * product)
- 递归的优缺点
- 使用递归函数的优点是逻辑简单清晰
- 缺点是过深的调用会导致栈溢出。
