三. 函数
3.1 调用函数
python里有很多有用的函数,我们可以直接调用
https://docs.python.org/2/library/functions.html#abs是python官网的函数解释
例如调用绝对值函数
abs()
>>> abs(9)
9
>>> abs(-9)
9
比较函数
cmp(x,y),如果xy,返回1;x==y,返回0
注上图中,是python2的函数,python3中没有了cmp函数,由operator代替
>>> import operator
>>> operator.lt(9,10)
True
- operator.le(a, b) #小于等于比较 lt是小于
- operator.eq(a, b) #等于比较
- operator.ne(a, b) #不等于比较
- operator.ge(a, b) #大于等于比较
- operator.gt(a, b) #大于比较
数据类型转换
int()转换为整数
>>> int(18.2)
18
>>> float(18.2)
18.2
>>> str(18.2)
'18.2'
>>>
函数还可以起别名,如下将max函数简化
>>> x=max
>>> x(1,2,3,4)
4
Hex()函数可以将参数转换成16进制结果
>>> hex(10)
'0xa'
>>> n1=255
>>> hex(n1)
'0xff'
>>> hex(1000)
‘0x3e8’
>>>
oct(10) #八进制函数转换
'0o12'
>>>
hex(10) #十六进制函数转换
'0xa'
>>>
chr(10) #ASCII码字符转换
'\n'
>>> chr(97)
'a'
>>>
bin(10) #二进制字符转换
'0b1010'
例子
n1 =
10
n2 =
100
t=
' hex number is: '
v=
' binary number is: '
print(
'n1'+t+
hex(n1)
,
'
\n
n2'+v+
bin(n2))
(\n换行可以参考如上写法)
3.2 定义函数
在python中定义函数需要def语句,然后在缩进块中编写函数体,返回值用return语句返回
例如定义一个wyz_pow(x)的函数(参考pow乘方函数)
def
wyz_pow(x
,y):
return
pow(x
,y)
print(wyz_pow(
2
,
3))
上图定义的my_abs(x)和内置的abs()看似没区别,但是还是有实质区别的,函数会识别里面的参数的可用性,例如abs(‘A’)就会报错,因为内置abs里的参数不能是字符串,但是my_abs(‘A’)结果就是A
返回多个值
比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标:
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.3 函数的参数
定义一个员工信息,包含姓名、部门、年龄、城市
def
employee(name
,department
,age
,city):
print(
'name:'
,name)
print(
'department:'
,department)
print(
'age:'
,age)
print(
'city:'
,city)
return
employee(
'wyz'
,
'IRE'
,
33
,
'NanJing
’)
在代码中调用employee必须将所有参数调用,否则报错,我们可以通过默认参数来省略部分内容,如下:
def
employee(name
,department
,age=
33
,city=
'NanJing'):
print(
'name:'
,name)
print(
'department:'
,department)
print(
'age:'
,age)
print(
'city:'
,city)
return
employee(
'wyz'
,
'IRE
’)
如果没有定义默认参数的值,直接值调用name和department就会报错如下
可见,默认参数降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个。
可变参数
可变参数顾名思义其参数是可变的,不是固定的,写法是在前面加个*号
比如正常情况下计算
a平方+b平方+c平方+...
def calc(numbers)
sum=0
for n in numbers:
sum=sum+n*n
return sum
但是调用的时候需要先组装一个list或者tuple
numbers((1,2,3,))
或者numbers([1,2,3])
如果定义函数的时候使用可变参数def calc(*numbers)
则调用的时候可以直接用numbers(1,2,3)来使用。
关键字参数
写法是前面加**
*args是可变参数,args接收的是一个list或者tuple
**kw是关键字参数,kw接收的是一个dict。
可变参数既可以直接传入 func(1,2,3),又可以组装成list或者tuple,再通过*args传入func(*(1,2,3));
关键字参数既可以直接传入 func(a=1,b=2),又可以先组装成dict,再通过**kw传入kw(**{‘a’:1,’b’:2})
def
person(name
, age
, **kw):
print(
'name:'
, name
,
'age:'
, age
,
'other:'
, kw)
return
person(
'wyz'
,
'33
’)
关键字参数有什么用?它可以扩展函数的功能。比如,在
person
函数里,我们保证能接收到
name
和
age
这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
>>> extra = {
'city':
'Beijing',
'job':
'Engineer'}
>>> person(
'Jack',
24, city=extra[
'city'], job=extra[
'job'])
name: Jack age:
24 other: {
'city':
'Beijing',
'job':
'Engineer'}
当然,上面复杂的调用可以用简化的写法:
>>> extra = {
'city':
'Beijing',
'job':
'Engineer'}
>>> person(
'Jack',
24, **extra)
name: Jack age:
24 other: {
'city':
'Beijing',
'job':
'Engineer'}
**extra
表示把
extra
这个dict的所有key-value用关键字参数传入到函数的
**kw
参数,
kw
将获得一个dict,注意
kw
获得的dict是
extra
的一份拷贝,对
kw
的改动不会影响到函数外的
extra
。
3.3 递归函数
函数是可以互相调用的,如果在一个函数内部调用自身,那就是递归函数
我们可以吧阶乘看成n个递归函数,
def
fact(n):
if n==
1:
return
1
return n * fact(n -
1)
print(fact(
1))
print(fact(
5))
就是在return的时候再次调用fact函数
但是使用递归函数需要放置栈溢出
上面的
fact(n)
函数由于
return n * fact(n - 1)
引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:
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)