函数
常用函数
类型转换
int('123')
123
>>> int(12.34)
12
>>> float('12.34')
12.34
>>> str(1.23)
'1.23'
>>> str(100)
'100'
>>> bool(1)
True
>>> bool('')
False
定义函数
def my_abs(x):
# 检查参数类型
if not isinstance(x, (int, float)):
# 当参数类型错误时 抛出错误
raise TypeError("bad operate Params type")
if x>0:
return x
else:
return -x
print(my_abs("-333")) #TypeError: bad operate Params type
定义一个空函数
def nop():
pass
# pass用作占位符
返回多个返回值
返回的其实为单一一个值,一个元组
,我们通过多个变量接收一个元组,按位置赋值
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, 60, math.pi / 6)
print(x, y)
151.96152422706632 70.0
若函数结束时没有
return
语句,就自动添加return None
函数参数
python的函数定义简单,灵活度很大.除了正常的必选参数外,还能使用默认参数、可变参数、关键字参数。
参数组合
在Python中,可以使用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,但是参数的定义顺序必须是:
必选参数、默认参数、可变参数、命名关键字参数和关键字参数
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
默认参数
必选参数在前,默认参数在后
def my_power(x, n=2):
total = 1
for s in range(1,n+1):
total = total*x
return total
print(my_power(2)) # 4
定义默认参数时: 默认参数必须指向不变对象,否则可变对象会成为函数内静态变量会在多次调用时变化,影响函数调用结果
使用默认参数即可省略参数,降低调用难度
可变参数
当不确定参数的个数时,可以使用可变参数,可以传入任意个参数,包括0个参数
def my_sum(*numbers):
sum=0
for x in numbers:
sum += x
return sum
print(my_sum(1,2,3,4)) # 10
numbers = [1,2,3,4,5]
#通过给list 或者 tuple前加* 将其元素变为可变参数
print(my_sum(*numbers)) #15
传入的可变参数在函数内部封装为一个元组
关键字参数
可以传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动封装为dict
def my_personFuc(name, age, **kw):
print("name:", name, "age:", age, kw)
my_personFuc("lyy", 24, city="luoyang") #name: lyy age: 24 {'city': 'luoyang'}
my_personFuc("wt", 20) # name: wt age: 20 {}
kwDict={"city":"beijing"}
# 解构字典
my_personFuc("yt", "25", **kwDict) # name: yt age: 25 {'city': 'beijing'}
对于关键字参数,对于直接传入的参数,采用
=
而且key
不能为str类似的字符串
命名关键字参数
#命名需要关键字 * ,在 * 之后的为命名关键字参数,
def my_keyPerson(name, age, *, city, job):
print(name, age, city, job)
#命名关键字必须传入参数名 否则会报错
my_keyPerson("lyy", 24, city="luoyang", job="iOS") # lyy 24 luoyang iOS
# 可以为可变参数隔开
def my_keyPerson1(name, age, *args, city, job):
print(name, age, args, city, job)
# 明明关键字可以有缺省值,这样调用时候可以不传入city参数
def my_keyPerson2(name, age, *, city='Beijing', job):
print(name, age, city, job)
递归函数
解决递归调用栈溢出的方法是通过尾递归优化
,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式
。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况
# 递归函数
def fact(n):
if n==1:
return 1
return n + fact(n - 1)
print(fact(10)) # 55
# 栈溢出
print(fact(1000)) #RecursionError: maximum recursion depth exceeded in comparison
#尾递归优化后
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)
目前包括Python在内的编程语言都没有做尾递归优化,因此类似上面的尾递归优化之后仍会导致栈溢出