函数
调用函数
函数名其实是指向函数对象的引用,因此可以直接把函数名赋值给一个变量。
def my_abs(x): if x >= 0: return x else: return -x
定义函数
def my_abs(x): if x > 0: return x else: return -x
什么也不做,用来作为占位符。
def nop(): pass
内置函数abs()会帮我们检查输入参数类型是否正确,不正确会raise TypeError,my_abs()函数可以通过内置函数isinstance()判断类型是否满足条件。
def my_abs(x): if not isinstance(x, (int, float)): raise TypeError('bad operand type') else: if x >= 0: return x else: return -x
返回多个值,其实返回的是元组tuple,可以依次赋值给不同的变量。
import math def move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y + step * math.sin(angle) return nx, ny
x, y = move(100, 100, 2)
函数的参数
位置参数
def power(x): return x*x
def power(x, n): s = 1 while n > 0: s *= x n = n - 1
默认参数
必选参数在前,默认参数在后,变化大的参数在前,变化小的在后。
def power(x, n = 2): s = 1 while n > 0: s *= x n = n - 1
默认参数有个最大的坑,演示如下:
def add_end(L=[]): L.append('end') return L add_end() add_end()
第一次调用得到['end'],第二次调用得到['end','end']。python函数在定义的时候,默认参数的值就被计算出来了,默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,下次调用时,默认参数的值就变了。
定义默认参数要牢记一点:默认参数必须指向不变对象!
修改后:
def add_end(L=None): if L is None: L = [] L.append('end') return L
可变参数
def calc(*numbers): sum = 0 for n in numbers: sum += n return sum
#直接输入参数,可以是0个
calc(1,2,3)
calc()
#对于list,tuple,调用可变参数
nums = [1,2,3]
calc(*nums)
关键字参数
可变参数允许传入0个或多个参数,这些参数在函数调用时自动组成list,而关键字参数允许传入0个或多个含参数名的参数,自动组成dict。
def person(name, age, **kw): print('name: ', name, 'age: ', age, 'other: ', kw)
person('Wayne', 20, city='Beijing', job='Engineer')
#可以直接传入dict类型
extra = {'city':'Beijing', 'job':'Engineer'}
person('Wayne', 20, **extra)#kw获得extra的拷贝,对kw的改变不会影响extra
命名关键字参数
检查某一项是否出现在关键字参数里
def person(name, age, **kw): if 'job' in kw: pass if 'city' in kw: pass pass
但是调用者仍可以传入不受限制的关键字参数
person('Wayne', 20, city='Beijing', addr='chaoyang', zipcode=123456)
如果要限制关键字参数的名字,可以使用命名关键字参数,如只接收job和city作为关键字参数
def person(name, age, *, city, job): print(name, age, city, job)
如果函数定义中已经有了一个可变参数,,后面跟着的命名关键字参数就不需要特殊分隔符*了
def person(name, age, *args, city, job): print(name, age, args, city, job)
上述五种参数可以混合使用,但要注意参数定义的顺序:必选参数,默认参数,可变参数,命名关键字参数,关键字参数
递归函数
要注意栈溢出,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。解决递归调用栈溢出的问题,可以使用尾递归进行优化,但大多数编程语言没有对尾递归做优化,python解释器也没有。
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)

浙公网安备 33010602011771号