一 函数的使用原则
储备知识:
函数的使用应该分为两个明确的阶段
1.定义阶段:只检测语法,不执行函数代码
def func():
print('from func')
2.调用阶段:会触发函数体代码的执行
func()
先定义后调用
def foo():
print('from foo')
bar()
foo()
def bar():
print('from bar')
二 函数定义的三种形式
1 有参函数
def func(x):#=>x 就是参数
pass
func(1)
2 无参函数
def bar()
print('wlcome to beijing!")
bar()
空函数
def func()
pass
二:函数调用的三种形式
1 语句形式:foo() 2 表达式形式:3*len('hello') 3 当中另外一个函数的参数:range(len('hello'))
register()#语句形式
def max2(x,y):
if x > y:
return x
else:
returny
res = max2(10,20)*12将函数的调用当做参数传给另一个函数
print(res)
三 函数的返回值
return 值:
注意点:
1.函数的返回值没有类型限制
2.函数的返回值没有个数限制
2.1返回多个值:多个返回值用逗号分隔开,返回是元组形式
def func()
print('from func')
return 1,1.1,'hello,[1,2,3]
res=func()
print(res,type(res)
2.2 返回1个值:返回的就是该值本身
def func()
return 123
res=func()
print(res,type())#=>123,int
2.3返回0个值或者干脆没有return:返回None
def func()
ruturn
pass
res=func()
print(res)
return除了有返回值得功能,还有结束函数执行的功能
函数内可以有多个return,但只要执行一次,整个函数就立即结束,并且将return后的值返回
def func():
print()
return
print()
return
print(3)
func()
四 函数参数的使用
一:函数的参数的两大类:
形式参数(形参):在定义函数阶段,括号内定义的参数/变量名称为形参.
实际参数(实参):在调用函数阶段,括号内传入的值/变量值成为实参.
ps:在调用函数阶段会将实参(值)的值绑定给形参(变量名),这种绑定关系只在调用函数时生效,在函数执行完毕后就会解除绑定
def func(x,y):
#x=1
#y=1
print(x,y)
func(1,2)
print(x)#=>报错 未定义变量名 x
print(y)
二:细分:
1.位置参数:
1.1位置形参:在定义阶段,按照从左到右的顺序依次定义的形参称之为位置形参
特点:但凡是an按照位置定义的形参,必须被传值,多一个少一个也不行
def func(x,y,z)
print(x,y,z)
func(1,2)#=>报错
func(1,2,3)
func(1,2,3,4)#=>报错
1.2 位置实参:在调用阶段,按照从左到右的顺序依次传入的值称之为位置实参
特点:
1.与形参一一对应
def func(x,y,z):
print(x,y,z)
func(2,1,3)
2. 关键字实参:在调用阶段,按照key=value的形式定义的实参称之为关键字实参
特点:可以完全打乱顺序,但依然能为指定的形参传值(总结:指名道姓为指定形参传值)
def func(x,y,z):
print(x=1,y=2,z=3)
func(x=1,y=2,z=3)
func(1,2,3)
func(z=3,y=2,x=1)
实参的形式可以是位置实参与关键实参混合使用,但必须遵循原则:
1 位置实参必须在关键字实参的前面
2 不能对同一形参重复传值
func(1,z=3,y=2)
func(z=3,1,y=2)#错误
func(1,z=3,x=2,y=3)#错误
3.默认形参:在定义阶段,就已经为形参赋值,该形参称之为默认形参
特点
1 定义阶段就已经有值意味着调用阶段可以不用传值
2 位置形参必须放到默认形参的前面
3.默认形参的值在函数定义阶段就已经固定死了,定义阶段之后的改动不会影响该值
4 默认形参的值通常应该是不可变类型
def func(x,y,z=100):
print(x,y,z)
func(10,20)#=>10,20,100
func(10,20,200)#=->10,20,200
def register(name,age,sex='male')
register('egon',18,)
register('lxx',38,)
register('cw','48')
def add_hobby(name,x,hobbies=None):
if hobbies is None:
hobbies=[]
hobbies.append(x)
print('%s的爱好有%s'%(name,hobbies))
add_hobby('egon','read')
add_hobby('wxx','eat')
add_hobby('alex','paio')
4.可变长参数:
可变长实参:指的是在调用阶段,实参值个数是不固定的,
实参无非两种形式(位置,关键字实参),对应的形参也必须有两种解决方案来分别接收溢出位置实参或者关键字实参
*----->溢出的位置实参
**----->溢出的关键字实参
def sum2(*x):#x=(1,2,3,4,5)
res=0
for i in x:
res+=i
return res
print(sum2(1,2,3,4,5))
4.1 *的用法
在形参前加*:*会将位置形参存成元组的形式,然后赋值给*后的形参名
def func(x,y,*z): #z=(3,4,5)
print(x,y,z)
func(1,2,[3,4,5])
func(*[1,2,3,4,5]) # func(1,2,3,4,5)
func(*[1,2,3]) #func(1,2,3)
在实参前加*:但凡碰到实参中带*的,先将实参打散成位置实参再与形参做对应
def func(x,y,*z)
func(1111,2222,*[1,2,3,4,5]) #func(1111,2222,(1,2,3,4,5))
4.2**的用法
在形参前加**:**会将溢出的关键字实参存为字典的形式,然后赋值给**后的形参名
def func(x,y,**z):#z={'c':3,'b':2,'a':1}
print(x,y,z)
func(1,y=2,a=1,b=2,c=3)
在实参前加**:但凡碰到实参中带**的,先将实参打散成关键字实参再与形参做对应
def func(x,y,z)
print(x,y,z)
func(1,**('y':2,'z':3)# func(1,z=3,y=2)
func(1,**{'a':2,'y':333,'z':3})#func(1,a=2,y=333,z=3)
def func(x,y,**z):
print(x,y,z)
func(**{'y':1,'x':2,'a':111,'b':2222})#func(1,z=3,y=2)
func(1,**{'a':2,'y':333,'z':3}) #func(1,a=2,y=333,z=3)#错误
def func(x,y,**z):
print(x,y,z)
func(**{'y':1,'x':2,'a':11111,'b':2222}) #func(y=1,x=2,a=1111,b=2222)
形参中:*arges,**kwargs
def func(x,args):
print(x)
print(args)
def func(x,**kwargs):
print(x)
print(kwargs)
*与**的应用:
def index(name,age,sex)
priint('index====>',name,age,sex)
会将wrapper函数接收的参数格式原封不动地转嫁给其他内部的index函数,必须要遵循的是index的参数ju参数规则
def wrapprt(*args,**kwargs): #args=(#args=('egon',) kwargs={'sex':'male','age':18}
print(args)
print(kwargs)
indx(*args,*kwargs):
wrapper(1,2,3,4,5,a=1,b=2,c=3)
wrapper('egon',sex='male',age=18)