函数的定义
对代码块和功能的封装和定义
先来个例子
例如:我们周末几个朋友要去出游,那出游前需要先做个策划
print('查找攻略') print('出行路线') print('出行计划') print('走起')
如果下一次有其他的朋友也想去那个地方出游,那她得自己重新去策划,非常麻烦,如果我们能够把这个计划系统的告诉她,那她直接执行就行了,非常方便,所以,很多人会写旅游攻略,会保存自己的出行计划,让别人去使用,那这个过程就是今天要说的函数了.
我们可以先去定义一个事情或者是功能,等到需要的时候直接去用就好了.那么这里定义东西就是一个函数
函数的结构
def 函数名():
函数体
我们使用def关键字来定义函数,函数的定义语法,这里的函数名的命名规则和变量的命名规则一样
def travel(): #定义函数 print('准备零食') print('出行计划') print('集合小伙伴') print('走起') travel() #调用函数
函数的执行流程
第一步:先定义函数
第二步:调用函数
第三... 执行函数体(代码块)
1def travel(): #定义函数 print('准备零食') 4 print('出行计划') 5 print('集合小伙伴') 6 print('走起') 7 2 travel() #调用函数,多次执行就多次调用
函数的返回值-return
还是上面的例子,我们出游结束之后,大家都会发朋友圈,来说说对本次出游的感受,那函数也是一样,当我们调用完之后,可以设置返回值
def travel(): print('准备零食') print('出行计划') print('集合小伙伴') print('走起') return ('今天玩的很开心') #反馈结果:今天玩的很开心,这里返回的是一个元组,多个字符串返回的结果就是元组,return对于后面返回的内容是没有限制的 print(travel()) #查看结果 print(travel()) 输出结果: 准备零食 出行计划 集合小伙伴 走起 今天玩的很开心
关于return,若我们不写return,那会返回值吗
def travel(): print('准备零食') print('出行计划') print('集合小伙伴') print('走起') print(travel()) 输出结果: 准备零食 出行计划 集合小伙伴 走起 None #说明我们在不写return时也会自动默认返回None
那我们写return,但不写返回结果,会出现什么情况呢?
def travel(): print('准备零食') print('出行计划') print('集合小伙伴') print('走起') return print(travel()) 输出结果: 准备零食 出行计划 集合小伙伴 走起 None #如果有return,但是不写结果,则返回还是None
如果在return下面再写内容,会怎样呢
def travel(): print('准备零食') print('出行计划') print('集合小伙伴') print('走起') return('今天玩的很开心') print('谢谢朋友们的陪伴,希望以后有更多的机会出游') print(travel()) 输出结果: 准备零食 出行计划 集合小伙伴 走起 今天玩的很开心 #return后面的内容都不再执行
总结
所以,return返回值,是将内容返回给调用者,也是例子中的travel()
1.可以是任意值,没有限制,若是多个字符串,则返回的是一个元组
2.若return后面什么都不写,则默认返回None,
3.若不写return,函数则默认返回None
4.函数在执行到return时就结束了,return以下的都不会执行,并且终止这个函数
函数的参数
实参
def func(name,age,addr): print(f'{name},{age},{addr}') func('小红',23,'北京') #这个就是实参
位置参数
def func(name,age,addr): print(f'{name},{age},{addr}') func('小红',23,'北京') #位置参数,位置必须一一对应 --实参
关键字参数
def func(name,age,addr): print(f'{name},{age},{addr}') func(name = '小红',age = 23,addr = '北京') #关键字参数,跟format格式化的用法有点相似
混合参数
def func(name,age,addr): print(f'{name},{age},{addr}') func( '小红',23,addr = '北京') #混合参数
注意:位置参数>关键字参数(位置参数一定要在关键字参数之前)
def func(name,age,addr): print(f'{name},{age},{addr}') func( '小红',addr = '北京',23) #报错 位置参数一定要在关键字参数之前,不然就会报错,因为位置参数要求一一对应
如果位置参数已经定义,不可用关键字参数再重新定义
def func(name,age,addr): print(f'{name},{age},{addr}') func( '小红',23,name = '北京') 报错 #这样不行,位置参数已经给name定好了,不能再重定义
行参
def func(name,age,addr):#这个就是形参 print(f'{name},{age},{addr}') func('小红',23,'北京')
位置参数
def func(name,age,addr):#位置参数,必须要一一对应 print(f'{name},{age},{addr}') func('小红',23,'北京')
默认参数
def func(name,age,addr='北京'):#默认参数,默认北京 print(f'{name},{age},{addr}') func('小红',23) 输出结果:小红,23,北京 def func(name,age,addr='北京'):#默认参数可以通过实参修改 print(f'{name},{age},{addr}') func('小红',23,'南京')
混合参数
def func(name,age,addr='北京'):#这个也是混合参数 print(f'{name},{age},{addr}') func('小红',23,'南京')
注意:位置参数>默认参数(位置参数一定要在默认参数之前)
def func(name,addr='北京',age): print(f'{name},{age},{addr}') func('小红',23) 报错,终其原因还是位置参数一一对应的问题
传参
给函数传递信息的时候将实际参数交给形式参数的过程被称为传参
传参是由实参到形参的过程.
动态参数
动态位置参数
动态位置参数表达形式:
*args
如果我们想输入的内容有很多,但又不太确定时,通过位置参数输入的话就没办法实现,怎么办呢,那就用到了动态位置参数,它会把你所想要的东西打包一下,放进去,至于你想放什么你自己定;就像1个书包一样,里面可以放你想放的任何东西.
def func(a,b,*args):--这个就是动态参数的表达形式 print(a,b,args) #3-6我不确定放什么就用 *args来聚合打包 func(1,2,3,4,5,6)#3,4,5,6就被我放进去了 输出结果:1 2 (3, 4, 5, 6) 它是以元组的形式呈现
对于放的位置而言,也是有要求的
def func(a,b,*args,c = 1): print(a,b,c,args) #位置参数>动态位置参数>默认参数 func(1,2,3,4,5,6) 运行结果: 1 2 1 (3, 4, 5, 6)
这是因为位置参数必须是一一对应,所以它必须放在最前面,不然把动态位置放在最前面的话,就全被动态参数给聚合了,那a和b没有值的话就会报错了,再说默认参数,如果放在动态参数之前,那它会被3覆盖掉,每次赋值,都会被覆盖,就起不到默认参数的作用了
def func(a,b,c = 1,*args): print(a,b,c,args) func(1,2,3,4,5,6) 运行结果: 1 2 3 (4, 5, 6)#每次运行都会被覆盖,起不到默认值的作用了
再来几个例子:
def func(a,b,*args):#聚合 print(a,b,*args)#打散 func(1,2,3,4,5,6) 输出结果: 1 2 3 4 5 6
lst = [1,2,3,4,5,6] def func(*args):#聚合 print(args) func(*lst) 输出结果: (1, 2, 3, 4, 5, 6)
lst = [1,2,3,4,5,6] def func(*args):#聚合 print(*args)#打散 func(*lst)#打散 输出结果: 1 2 3 4 5 6
动态关键字参数
动态关键字参数(动态默认参数)表达形式:
**kwargs
如果我们默认的参数有很多,不确定时,可以通过动态默认参数来实现
def func(a,b,**kwargs): print(a,b,kwargs) func(1,2,c = 3,d = 4) 输出结果: #**kwargs输出的结果以字典的形式呈现 1 2 {'c': 3, 'd': 4}
那我们来看看参数的优先顺序
def func(a,b,*args,c = 1,**kwargs): print(a,b,args,kwargs) func(1,2,4,5,6,f = 3,d = 4,h = 8) 输出结果: 1 2 1 (4, 5, 6) {'f': 3, 'd': 4, 'h': 8}
位置参数>动态位置参数>默认参数>动态关键字参数(动态默认参数)
如果想接收所有的参数 万能 无敌
def func(*args,**kwargs): print(args,kwargs) func(1,2,3,4,5,6,a = 3,b = 5) 输出结果: (1, 2, 3, 4, 5, 6) {'a': 3, 'b': 5}
函数的注释
自己添加注释
在代码块最上面输入''' ''' ,操作下回车键
def func(a,b,*args): ''' :param a: :param b: :param args: :return: ''' print(a,b,args) func(1,2,3,4,5,6)
如果要查看别人额函数注释,如果调取
函数名.__doc__
def func(a,b,*args): print(a,b,args) func(1,2,3,4,5,6) print(func.__doc__) 输出结果: :param a: :param b: :param args: :return:
函数名使用
1.可以查看函数名的内存地址
2.函数名可以当做值去赋给一个变量
3.函数名可以当参数传递给函数
4.函数名可以当做函数的返回值
5.函数名可以当做一个元素,存放在一个容器中
查看函数名的内存地址
def func(): print(1) print(func) 打印结果:#这个就是func的函数名的内存地址 <function func at 0x00000262845D1E18>
函数名可以当做值去赋给一个变量
def func(): print(1) return "函数名可以当作值赋给一个变量" a = func # func变量名赋给了a,那调用a就是在执行这个函数 print(a()) 打印结果: 1 函数名可以当作值赋给一个变量
函数名可以当参数传递给函数
def f1(): print(2) return '这个是结果' def func(msg): print(1) print(msg()) func(f1)#f1作为参数传给msg,这时f1函数名已经变成msg,然后在func里执行msg(),将会调用f1的结果,所以在进行传递参数时,尽量不要加括号,不然会改变运行结果. 输出结果: 1 2 这个是结果
看一下这种情况
def f1(): print(2) def func(msg): print(1) return msg print(func(f1))#这个才是正确的使用方式 运行结果: 1 <function f1 at 0x000002ACEF741E18>
函数名可以当做函数的返回值
def func(): n = 100 def foo(): n = 100 def f1(): print(n) return '结束' return f1 return foo print(func()()()) 输出结果: 100 结束
def foo(): print(1) return'我想要的结果,别给我改' def func(): print(2) ret = foo() return ret def func2(): print(3) msg = func() return msg print(func2()) 返回结果: 3 2 1 我想要的结果,别给我改
函数名可以当做一个元素,存放在一个容器中
lst= [func,f1,f2]可以把多个函数放在一个列表中,如果要一次性调用多个函数,可对这个列表进行循环,批量调取.