s = ‘hello’
这里我们想求出这个字符串的长度,可以用代码:
for i in s: n=0 n+=1 print(n)
但是当我们要求下一个字符串的长度的时候,我们就又要敲一遍这个代码,这样一旦要求的很多,这样的方法就会很繁琐。
所以这里我们就要函数了
一、函数
函数就是工具,并且函数一定是要先定义后调用的(函数名+括号)
def my_len(): n = 0 for i in s n+=1 print(n)
当我需要这个函数的时候,就用my_len()调用就行了
但是以上我做的这个简单的函数,存在以下两个问题。
1.没有返回值,只能固定的执行打印操作。
2.只能够固定的统计某一个容器类型的长度
二、函数的返回值
函数内想要返回给用户调用值,必须用关键字return
1.不写return:函数默认返回None
1 def func(): 2 print('abcd') 3 res = func() 4 print(res)#None
2.只写return:除了可以返回值(None)之外,还可以直接结束整个函数运行
1 def func(): 2 l = ['zzj','zzp','lzx','yzy'] 3 while True:
for i in l: 4 if i == 'zzp'#当i为zzp的时候,直接结束函数运行 5 return 6 res = func()#zzj 7 print(res) #None
3.写return返回一个值:这个值可以是pyth任意数据类型
def func(): return'123' def func1(): return[1,2,3] def func2(): return {'name':'zzj'} def func3(): return (1,2,3) def func4(): return {1,2,3,4,5} def func5(): return True
print(func(),func1(),func2(),func3(),func4(),func5())
以上结果都能打印.
4.写return返回多个值:return会自动将多个值以元组的形式返回给调用者。
4.1.为什么组织成元组返回
函数不希望自己处理的结果被修改
1 def func(): 2 return1,2,3,4 3 res = func() 4 print(res)#(1, 2, 3, 4)
4.2.如何不返回元组
提前自己加上数据类型
def func(): return [[1,2,3],[4,5,6],[7,8,9]] res = func() print(res)#[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
5.函数参数概要
还是同样的一题,我们求s的长度,但是这一次我们带入参数,这样就能让函数真正成为一个工具,当你想用这个功能,将变量名写进去就行了
1 def my_len(args): #需要一个参数 2 n = 0 3 for i in args: 4 n+=1 5 return n 6 print(my_len('hello')) #5 7 print(my_len([1,2,3,4,5])) #5
函数参数的两大类型:
1.形参:在函数的定义阶段,括号内写的变量名,叫做函数的形式参数,简称 形参
2.实参:在函数的调用阶段,括号内实际传入的值,叫做实际参数,简称 实参
形参与实参的关系
形参就相当于变量名,而实参就相当于变量的值
函数调用传参的过程,就给形参变量名赋值的过程
PS:形参和实参的绑定关系只在函数的调用阶段有效,函数运行结束关系自动解除,只有在函数内部有效,函数外部无任何影响。
函数的简易结构:def 函数名(形参1,形参2…)
函数体代码1
函数体代码2
…
return 函数的返回值
小知识点:查看函数注释功能:print(help(函数名))
6.位置参数
位置参数:在函数定义阶段,按照位置从左到右依次书写的变量名,叫做函数位置形参,位置形参在调用的时候,必须为其赋值。
def my_max(x,y): if x>y: return x else: return y
print(my_len(12,20))
在函数调用的时候,少一个实参或多一个实参都不行,位置实参会按照位置一一对应给形参
除了一一对应的方式,还有第二种方式:指名道姓的传参数。
def my_max(x,y): if x>y: return x else: return y res = my_max(x= 50,y = 20) print(res)
注意:在函数的调用阶段,位置参数和关键字参数可以混合使用
但是必须保证:
1.位置参数必须在关键字参数的前面(越短的越靠前,越长越复杂的越靠后)
2.同一形参不能被多次赋值
7.默认值参数
在函数的定义阶段,形参(变量名)就已经被赋值了
def my_max(x,y=100): if x>y: return x else: return y res = my_max(200) print(res) #200 res1 = my_max(200,1000) print(res1) #1000 res2 = my_max(y=200,x=1000) print(res2) #1000
当形参接受到的值比较单一的情况下,通常可以考虑用默认值形参
def register(username,age,gender='male'): print(username,age,gender) register('jason',18) register('tank',28) register('egon',84) register('kevin',58) register('xiaohou',17,'female')
def info(username,hobby,l=None): if l == None: l = [] l.append(hobby) print('%s 的爱好是 %s'%(username,l)) info('jason','study') info('tank','生蚝') info('kevin','喝腰子汤') info('egon','女教练')
8.可变长参数
站在调用函数传递实参的角度,实参的个数是不固定的,那也就意味着形参也不固定。站在形参的角度,可用*和**来接收多余的(溢出的)位置参数和关键字参数
站在形参的角度看 *:
形参中的*会将多余的(溢出的)位置实参,同一用元组的形式处理,传递给*后面的形参名。
def func(x,y,*z): print(x,y,z) #(1, 2, (3, 4, 5, 6, 7, 8, 9)) func(1,2,3,4,5,6,,7,8,9)
站在实参的角度看*:
会将其打散成位置实参一一传入
def func(x,y,z): print(x,y,z) l = [1,2,3] a,b,c = l func(a,b,c)
def func(x,y,z): print(x,y,z) func(*[1,2,3])#等价于func(1,2,3)
站在形参的角度看**:
会接收所有多余的关键字参数,并将关键字参数转换成字典的形式,字典的key就是关键字的名字。
def func(x,y,**z): print(x,y,z) func(x=1,y=2,z=1,a=1,b=4,c=3)
站在实参的角度看**:
def func(x,y,z): print(x,y,z) func(**{'x':1,'y':2,'z':3})#等价于 func(x = 1,y = 2,z = 3)
总结 * 与 **
*在形参中能够接受多余的位置参数,组织成一个元组赋值给*后面的变量名
**在形参中能够接受多余的关键字参数,组织成一个字典赋值给**后面的变量名
*在实参中能够将,列表、元组、集合、字符串打散成位置实参的形式传递给函数
**在实参中能将字典打散成 key = value的形式,按照关键字参数传递给函数
注意:python推荐形参*和**通用的写法
1 def func(*x,**y): 2 print(x,y) 3 func(1,2,3,4,5,6,a =1,b = 2,c = 3) #(1, 2, 3, 4, 5, 6) {'a': 1, 'b': 2, 'c': 3}