一、调用内置函数
- 官方文档查看函数
http://docs.python.org/3/library/functions.html#abs
二、自定义函数
- 定义一个函数
def my_abs(x):
if x >= 0:
return x
else:
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 x
else:
return -x
- 默认参数
- 注意:默认参数必须指向不变对象!
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
#调用时
power(2) #实际是调用power(2,2)
- 可变参数
# 可变参数
#定义可变参数需要在参数前加*符号
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return 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 1
return n * fact(n - 1)
- 解决递归调用栈溢出的方法是通过尾递归优化; 主要是要把每一步的乘积传入到递归函数中:
def fact_iter(num, product=1):
if num == 1:
return product
return fact_iter(num - 1, num * product)
- 递归的优缺点
- 使用递归函数的优点是逻辑简单清晰
- 缺点是过深的调用会导致栈溢出。