一、函数
功能:包裹一部分代码 实现某一个功能 达成某一个目的
特点:
""" 特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理 函数基本格式 函数的定义: def 函数名(): code1 code2 函数的调用: 函数名() """
1、函数定义:
# 定义函数 def func(): print("我是一个函数")
2、函数调用
func()
3、函数命名
""" 函数命名 字母数字下划线,首字符不能为数字 严格区分大小写,且不能使用关键字 函数命名有意义,且不能使用中文哦 """
""" 驼峰命名法: (1) 大驼峰命名法:每个单词的首字符大写 (类:面向对象) mycar => MyCar mydesk => MyDesk (2) 小驼峰命名法:除了第一个单词的首字符小写之外,剩下每个单词首字符大写 mycar => myCar mydesk => myDesk mycar => my_car mydesk => my_desk symmetric_difference """
例:
# 函数的定义处 def cfb_99(): for i in range(1,10): for j in range(1,i+1): print("%d*%d=%2d " % (i,j,i*j) , end="") print() # 函数的调用处 for i in range(10): cfb_99()
二、函数的参数
""" 参数: (1)形参:形式参数,在函数的定义处 (2)实参:实际参数,在函数的调用处 形参: 普通形参(位置) , 默认形参 , 普通收集形参 , 命名关键字形参 , 关键字收集形参 实参: 普通实参,关键字实参 遵循原则: 形参和实参要一一对应 """
1、普通形参
"""hang,lie是函数的普通形参""" def s_star(hang,lie): i = 0 while i < hang: j = 0 while j < lie: print("*",end="") j+=1 print() i+=1 # 函数的调用处 """10,10 是函数的实际参数""" s_star(10,10) s_star(3,8)
2、默认形参
"""hang,lie身上有默认值,是默认形参""" def s_star(hang=10,lie=10): i = 0 while i < hang: j = 0 while j < lie: print("*",end="") j+=1 print() i+=1 # 函数的调用处 """ 在函数调用时: 如果给予实参,那么直接使用实际参数 如果没有给予实参,那么使用参数默认自带的值 """ # s_star() # s_star(3,8) s_star(4)
3、普通形参+默认形参
# 函数的定义处 """默认形参必须跟在普通形参的身后,顺序是一定的""" def s_star(hang,lie=10): i = 0 while i < hang: j = 0 while j < lie: print("*",end="") j+=1 print() i+=1 # 函数的调用处 # s_star(3,3) s_star(3) # s_star() error
4、关键字实参
# 函数的定义处 def s_star(hang,a,b,c,d,lie=10): i = 0 while i < hang: j = 0 while j < lie: print("*",end="") j+=1 print() i+=1 # 函数的调用处 # s_star(hang=4,a=1,b=2,c=3,d=4,lie=5) s_star(c=3,d=4,lie=5,hang=4,a=1,b=2)
5、普通实参 + 关键字实参
def s_star(hang,a,b,c,d,lie=10): i = 0 while i < hang: j = 0 while j < lie: print("*",end="") j+=1 print() i+=1 # 函数的调用处 """关键字实参必须跟在普通实参的身后,顺序是一定的""" # s_star(5,6,99,c=7,d=8,lie=9) # s_star(c=7,d=8,lie=9,5,6,99) error s_star(5,1,c=2,d=3,lie=10,b=5) # ok # s_star(5,1,c=2,d=3,lie=10,a=5) error s_star(5,1,c=2,d=3,lie=10,,,,b=5) s_star(5,1,c='',d='',lie=10,,,,b=5)
6、区分默认形参和关键字实参
# 函数的定义处 def lol31_gameteam(top="aa",middle="bb",bottom="cc",jungle="ss",support="dd"): print("{}".format(top)) print("{}".format(middle)) print("{}".format(bottom)) print("{}".format(jungle)) print("{}".format(support)) # 函数的调用处 lol31_gameteam() lol31_gameteam(top="qq",middle="ww",bottom="ee",jungle="rr",support="tt")
""" 默认参数和关键字实参 在写法上一模一样 一个是在函数的定义处 一个是在函数的调用处 """
三、收集参数
""" 收集参数: (1)普通收集参数: 专门用来收集多余的没人要的普通实参 def func(*args): code *args => arguments(参数) 在args这个参数的前面加上一个*表达普通收集参数,形成一个元组 """
基本使用:
# 基本使用 def func(a,b,c,*args): print(a,b,c) print(args) # (1,2,3,4,5,5,6,7,8) func(1,2,3,4,5,5,6,7,8) # 计算任意个数的累加和 def func(*args): total = 0 for i in args: total += i print(total) func(1,2,3,4,6,10,11,100)
""" (2)关键字收集参数 : 专门用来收集多余的没人要的关键字实参 def func(**kwargs): code1... **kwargs => keyword arguments 在kwargs参数的前面加上2个**表达关键字收集参数,形成一个字典 """
基本使用:
# 基本使用 """ def func(a=1,b=2,c=3,**kwargs): print(a,b,c) print(kwargs) # {'f': 1, 'g': 2, 'j': 3} func(f=1,g=2,j=3,a=15,b=16,c=17) """
例:
任意个数字符串的拼接
def func(**kwargs): print(kwargs) # 定义一个字典,存放每一位同学的身份 dic = {"monitor":"班长","class_flower":"班花","class_grass":"班草"} strvar1 = "" strvar2 = "" # 遍历字典中的键值对 for k,v in kwargs.items(): print(k,v) # 判断键是否在字典当中,如果在,获取对应的身份,拼装成字符串 if k in dic: strvar1 += dic[k] + ":" + v + " " else: strvar2 += v + "," # 去掉右边多余的 和,形成最后的效果 print(strvar1.strip()) print("吃瓜群众:"+ strvar2.rstrip(",")) func(monitor="aa",class_flower="bbb",class_grass="cc",eatgua1="dd",eatgua2="ee",eatgua3="ff")
四、命名关键字参数
""" 定义命名关键字参数的两种方式: (1)def func(a,b,*,c) c是命名关键字 (2)def func(*args,c,**kwargs) c是命名关键字参数 在函数调用时,必须使用命名关键字参数来进行赋值 """
定义方式一、
# 定义方式一 def func(a,b,*,d,c): print(a,b) print(d) print(c) func(1,2,d = 3,c=10)
定义方式二、
def func(*args,c,**kwargs): print(args) print(c) print(kwargs) func(1,2,3,4,5,6,a=1,b=2,d=6,c=100)
1、关于* 和 ** 的使用方法
关于 *
""" * 和 ** 在函数的定义处,用来做收集操作,打包 * 和 ** 在函数的调用处,用来做打散操作,解包 """ def func(a,b,*,c,d): print(a,b) print(c,d) lst = [1,2] # *把列表里面的所有元素拿出来,当成参数一个一个赋值给func进行调用 func(*lst,c=3,d=4)
关于 **
def func(a,b,*,c,d): print(a,b) print(c,d) dic = {"c":3,"d":4} # **把字典里面的所有元素拿出来,拼装成键=值的参数形式,赋值给func进行调用 func(1,2,**dic,) # func( c=3, d=4 )
组合
# *和**的组合 func(*lst,**dic) strvar = "abc" print(*strvar)
2、参数定义顺序
# ### 当所有参数都在一起的时候,按照什么顺序定义呢? # 参数定义的顺序:普通参数 -> 默认参数 -> 普通收集参数 -> 命名关键字参数 -> 关键字收集参数 # 收集到所有的实参: def func(*args,**kwargs)
例题:
def f1(a, b, c=0, *args, **kw): print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw) def f2(a, b, c=0, *, d, **kw): print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw) # 以上两个函数 打印结果 #(一) # f1(1, 2) # a=1,b=2,c=0,args=(),kw={} # f1(1, 2, c=3) # a = 1 ,b=2,c=3,args=(),kw={} # f1(1, 2, 3, 'a', 'b') #a=1,b=2,c=3,args=(a,b),kw={} # f1(1, 2, 3, 'a', 'b', x=99) #a=1,b=2,c=3,args=(a,b),kw={x:99} # f2(1, 2, d=99, ext=None) #a=1,b=2,c=0,d=99,{ext:None} #(二) # args = (1, 2, 3, 4) # kw = {'d': 99, 'x': '#'} # f1(*args, **kw) # a=1,b=2,c=3,args=(4,),kw={d:99,x:#} '''f1(1,2,3,4,d=99,x="#")''' #(三) # myargs = (1, 2, 3) # mykw = {'d': 88, 'x': '#'} # f2(*myargs, **mykw) #a=1,b=2,c=3,d=88,kw={x:#} '''f2(1,2,3,d=88,x=#)''' #(四) def f1(a, b, c=0, *args,d,**kw): print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw) print(d) f1(1,2,3, 'a', 'b',d=67, x=99,y=77) #a=1,b=2,c=3,args=(a,b),kw={x:99,y:77} d:67
五、return 返回值
""" 自定义函数的返回值,return 可以把值返回到函数的调用处 (1) return + 六大标准数据类型 , 还有类和对象,函数 如果不定义return , 默认返回的是None (2) 在执行完return之后,立刻终止函数,后面的代码不执行 """
1、return的返回类型
def func(): # return 1 # return 3.14 # return "abc" # return [] # return () # return {"a":1} pass res = func()
# 如果不定义return , 默认返回的是None print(res) # None
2.在执行完return之后,立刻终止函数,后面的代码不执行
def func(): print(1) print(2) return 3 print(4) print(5) res = func() print(res) def func(): for i in range(3): if i == 2: return 1 print(i) res = func() print(res)
3、模拟简单的计算器 + - * /
def func(sign,num1,num2): if sign == "+": res = num1 + num2 elif sign =="-": res = num1 - num2 elif sign == "*": res = num1 * num2 elif sign == "/": if num2 == 0: return "除数不能为0 , 脑弟!" res = num1 / num2 else: return "这个本计算器真算不了" return res res = func("+",3,5) res = func("-",10,20) res = func("*",10,20) res = func("/",20,10) res = func("/",20,0) res = func("&",20,0) print(res)
六、练习
''' 1.定义函数:打印用户传入的容器类型数据长度 2.定义函数:参数为容器类型数据,打印所有奇数位索引对应的元素 3.定义函数:,接收一个参数(可迭代性数据),用_让元素相连成字符串,打印出来 4.定义函数:接收任意个参数,打印其中的最小值 5.定义函数:传入一个参数n,返回n的阶乘(5! = 5*4*3*2*1) 6.写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等), 将容器中的每个元素依次添加到新的列表中返回 #例:传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33) 7.写函数,用户传入要修改的文件名,与要修改的内容,执行函数,修改操作 8.写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数 9.写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,返回处理后的结果. #例:参数为:dic = {"k1": "v1v1", "k2": [11,22,33,44]} 10.传入多个一级容器类型数据,计算元素总个数 '''
# 1.定义函数:打印用户传入的容器类型数据长度 def func(container): len(container) func = lambda contaner : len(contaner) res = func([1,2,3,45]) print(res)
# 2.定义函数:参数为容器类型数据,打印所有奇数位索引对应的元素 def func(container): i = 0 while i<len(container): if i % 2 == 1: print(container[i]) i+=1 func([1,2,3,43,5,5]) # 方法二 def func(container): return container[1::2] # 1,3,5,7, ... res = func([1,2,3,43,5,5]) print(res)
# 3.定义函数:,接收一个参数(可迭代性数据),用_让元素相连成字符串,打印出来 def func(container): return "_".join(container) func(["1","2","3","45"]) print(res) def func(container): strvar = "" for i in container: strvar += str(i) + "_" return strvar.rstrip("_") res = func([1,2,5,7]) print(res)
# 4.定义函数:接收任意个参数,打印其中的最小值 # 正常 def func(*args): # print(args) lst = list(args) lst.sort() return lst[0] res = func(1,5,9,-100) print(res) # 升级 def func(*args): lst_new = [] print(args) for i in args: if isinstance(i,(int,float)): lst_new.append(i) elif isinstance(i,(list,tuple,dict,set)): if isinstance(i,dict): i = i.values() # print(i.values()) for j in i: if isinstance(j,(int,float)): lst_new.append(j) lst_new.sort() return lst_new[0] res = func(1,5,9.1,"你好",[1,19,100],(99,-7),{"a":1000,"b":3,"c":"abc"},{98,-10}) print(res)
# 5.定义函数:传入一个参数n,返回n的阶乘(5! = 5*4*3*2*1) def func(n): total = 1 for i in range(n,0,-1): total *= i return total res = func(6) print(res)
# 6.写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等), # 将容器中的每个元素依次添加到新的列表中返回 #例:传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33) # 方法一 def func(*args): lst = [] print(args) for i in args: for j in i: lst.append(j) return lst res = func([1,2,3],(22,33)) print(res) # 方法二 def func(*args): # print(args) return list(args) func(*[1,2,3],*(22,33))
# 7.写函数,用户传入要修改的文件名,与要修改的内容,执行函数,修改操作 def func(file,str1,str2): # 打开文件读取所有内容 with open(file,mode="r+",encoding="utf-8") as fp: strvar = fp.read() print(strvar) # 替换字符串 strvar = strvar.replace(str1,str2) # 重写写入 with open(file,mode="w+",encoding="utf-8") as fp: fp.write(strvar) func("ceshi.txt","好的","坏的") def func(file,str1,str2): with open(file,mode="r+",encoding="utf-8") as fp: strvar = fp.read() strvar = strvar.replace(str1,str2) # 把光标移动到开头 fp.seek(0) # 没有参数等于没有截取,相当于清空 fp.truncate() fp.write(strvar) func("ceshi.txt","坏的","好的")
# 8.写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数 def func(strvar): # dic = {"num":0,"word":0,"space":0,"other":0} dic = {}.fromkeys(["num","word","space","other"] ,0 ) print(dic) for i in strvar: if i in "0123456789": dic["num"] += 1 elif i.lower() in "abcdefghijklmnopqrstuvwxyz": dic["word"] += 1 elif i == " ": dic["space"] += 1 else: dic["other"] += 1 return dic strvar = "234JKJK^&* " res = func(strvar) print(res) def func(strvar): # dic = {"num":0,"word":0,"space":0,"other":0} dic = {}.fromkeys(["num","word","space","other"] ,0 ) for i in strvar: if i.isdecimal(): dic["num"] += 1 # elif i.isalpha(): isalpha 可以在字节流模式下,分辨出中文(False)和字母(True) elif i.encode().isalpha(): dic["word"] += 1 elif i.isspace(): dic["space"] += 1 else: dic["other"] += 1 return dic strvar = "234JKJK^&* 你好" res = func(strvar) print(res)
# 9.写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,返回处理后的结果. #例:参数为:dic = {"k1": "v1v1", "k2": [11,22,33,44]} def func(dic): for k,v in dic.items(): # print(k,v) if isinstance(v,(str,list,tuple)) and len(v) > 2: dic[k] = v[:2] return dic dic = {"k1": "v1v1", "k2": [11,22,33,44],"k3":123} res = func(dic) print(res) # 10.传入多个一级容器类型数据,计算元素总个数 def func(*args): total = 0 for i in args: total += len(i) return total res = func([1,2,3],(3,4),{6,7,8},{"a":1,"b":2}) print(res)