定义函数的三种形式
1.无参函数:
def foo(): print('from foo') foo()
2.有参函数
def bar(x, y): print(x, y) bar(1, 2)
3.空函数
def func():
pass
调用函数的三种形式
方式1 :
def foo(): print('from foo') foo() # 语句形式
方式2:
def foo(x, y): res = x + y return res res = foo(1, 2) * 100 # 表达式形式 print(res)
方式3:可以当作函数传给另外一个参数
def max2(x, y): if x > y: return x else: return y res=max2(max2(1,2),3) print(res)
函数的返回值需要注意:
1.返回值没有类型限制
2.返回值没有个数限制
返回1个值:调用函数的结果就是一个值
返回多个值:调用函数拿到的结果就是一个元组
1 def bar(): 2 pass 3 def foo(): 4 return [1,2],3,4,(5,6),{7,8},bar() 5 res=foo() 6 print(res)
返回0个值,或者不写return:调用函数拿到的结果就是一个None
1 def func(): 2 print('from foo') 3 # return 4 res=func() 5 print(res)
二:return关键字:return是函数结束的标志,函数内可以有多个return,但只要执行一次,整个函数就结束
# def f1(): # print('1') # return 1 # print('2') # return 2 # print('3') # return 3 # res=f1() # print(f1)
return可以结束掉整个函数
1 def foo(): 2 count=1 3 while Ture: 4 print(count) 5 if count == 3: 6 return 7 count+=1 8 foo()
函数的参数分为两大类:
1.形参:指的是在定义函数阶段括号内指定变量名,即形参本质就是 '变量名'
2.实参:指的是在调用函数阶段括号内传入的值,即形参本质就是 '值'
形参与实参的关系:在调用函数时,会将实参(值)绑定 給形参(变量名),这种绑定关系在函数调用时临时生效,在调用结束后就是失效
def foo(x,y): #x=1 y=2 # x=1 # y=2 print(x,y) foo(1,2)
形参与实参的具体分类:
一.位置参数
位置形参:在定义函数阶段按照从左到右的顺序依次定义的形参,称之为位置形参
注意:但凡按照位置定义的形参,必须被传值,多一个不行,少一个也不行
def foo(x, y): print(x, y) foo(1, 2) # foo(1, 2, 3) # foo(1)
位置实参:在定义函数的阶段按照从左到右的顺序依次传入的值,称之为位置实参
注意:但凡按照位置定义的实参,会与形参一一对应
def foo(x, y): print(x, y) foo(1, 2)
二:关键字参数
关键字实参:在调用函数阶段,按照key=value的形式指名道姓地为形参传值
注意:
1.可以完全打乱顺序,但仍然能指名道姓为指定的形参传值
2.可以混合使用位置实参与关键字实参,但是必须注意:
1 位置实参必须放到关键字实参的前面 2 不能对一个形参多次重复赋值 def foo(name, age): print(name, age) foo(age=18, name='cao') foo('bai',age=18)
三 默认参数
默认参数:指的是在定义函数阶段,就已经为某个形参赋值了,该形参称之为有默认值的形参,简称默认形参
注意:
1.在定义阶段就已经被赋值,意味着在调用阶段可以不用为其传值
2.位置形参应该放到默认形参的前面
3.默认参数的值在函数定义阶段就已经固定死了
m=10 def foo(x,y=m): print(x,y) m=20 foo(1)
4.默认参数的值通常应该是不可变类型
def register(name,hobby,l=None): if l is None: l=[] l.append(hobby) print('%s 的爱好为%s'%(name,l)) register('cao','洗澡') register('bai','吃') def register(name,hobby,l=[]): l.append(hobby) print('%s 的爱好为%s'%(name,l)) register('cao','洗澡') register('bai','吃')
def foo(x, y=2): print(x, y) foo(1) foo(1, 3) foo(y=3, x=1)
位置形参vs默认形参
对于大多数形况下传的值都相同的,应该定义成默认形参 对于大多数形况下传的值都不相同的,应该定义成位置形参 def register(name, age, sex='男'): print(name, age, sex) register('cao', 19, ) register('bai', 20)
register('li', 20,'女')
四 可变长度的参数
站在实参的角度,参数长度可变指的是在调用函数时,传入的实参值的个数不固定
实参的定义方式无非两种:位置实参,关键字实参,对应着形参也必须有两种解决方案:*与**,类分别应对溢出的位置实参与关键字实参
1.在形参中带*:会将调用函数时溢出的位置实参保存成元组的形式,然后赋值给*后的变量名
def foo(x,y,*z): #z=(3,4,5,6) print(x,y,z) foo(1,2,3,4,5,6)
2.在形参中带**:会将调用函数时溢出关键字实参保存成字典的形式,然后赋值给**后的变量名
def foo(x,y,**z): #z={'z':3,'a':1,'b':2} print(x,y,z) foo(1,y=2,a=1,b=3,c=4)
五 命名关键字参数: 放到*与**之间的参数称之为命名关键字参数
注意: 命名关键字参数必须按照key=value的形式传值
# def foo(x,y,*args,m,n,**kwargs): #args=(3,4,5,6,7,8) # print(x,y) # 1,2 # print(args) #(3,4,5,6,7,8) # print(m,n) #222,333 # print(kwargs) # # foo(1,2,3,4,5,6,7,8,n=333,m=222,a=1,b=2) # def foo(*,x=1,y): # print(x) # print(y) # # foo(y=2222,x=1111) # foo(y=2222) def foo(x,y=1,*args,m,**kwargs): print(x) print(y) print(args) print(m) print(kwargs) foo(3,m=33,c=1,n=2)