1 python的keyword-only参数及解包
1.1 python的keyword-only参数
描述
python3.0开始支持使用keyword-only参数,函数定义中def func(a,b=vb,pargs,kvar=kval,**kargs),其中的kvar入参调用使用只能按关键字参数(keyword-only)进行调用,kvar这样的入参可以有多个,但是必须出现在pargs和*kargs之间,前面的pargs也可以为*。
kvar如果不按关键字参数调用,会报错 TypeError。
kvar前面的*,不能收集多余的位置参数。
kvar支持默认参数,并且默认参数可以放在非默认参数前面。
示例
>>> name='梯阅线条';url='tyxt';des='软件测试开发';arts=9555 >>> def kwolf(name,*pargs,arts): print(name,pargs,arts) # arts 必须按关键字参数调用 >>> kwolf(name,url,des,arts=arts) 梯阅线条 ('tyxt', '软件测试开发') 9555 >>> kwolf(name,arts=arts) 梯阅线条 () 9555 # arts 没有按关键字参数调用,报错 TypeError >>> kwolf(name,url,des) Traceback (most recent call last): File "<pyshell#8>", line 1, in <module> kwolf(name,url,des) TypeError: kwolf() missing 1 required keyword-only argument: 'arts' >>> def kwolf(name,*,des,arts): print(name,des,arts) # keyword-only 参数 前面也可以为* >>> kwolf(name,arts=arts,des=des) 梯阅线条 软件测试开发 9555 >>> kwolf(arts=arts,des=des,name=name) 梯阅线条 软件测试开发 9555 # keyword-only 参数前面的*,不能收集多余的位置参数 >>> kwolf(name,des,arts) Traceback (most recent call last): File "<pyshell#14>", line 1, in <module> kwolf(name,des,arts) TypeError: kwolf() takes 1 positional argument but 3 were given # keyword-only 参数未送值,报错 >>> kwolf(name) Traceback (most recent call last): File "<pyshell#15>", line 1, in <module> kwolf(name) TypeError: kwolf() missing 2 required keyword-only arguments: 'des' and 'arts' >>> def kwolf(name,*,des='keywordonly默认值',arts): print(name,des,arts) # keyword-only 参数支持默认值,默认参数可以放在非默认参数前面 >>> kwolf(name,arts=arts) 梯阅线条 keywordonly默认值 9555 >>> kwolf(name,arts=arts,des=des) 梯阅线条 软件测试开发 9555 >>> def kwolf(name,*pargs,des,**kargs): print(name,pargs,des,kargs) >>> kwolf(name,url,des=des,arts=arts) 梯阅线条 ('tyxt',) 软件测试开发 {'arts': 9555} # keyword-only 参数必须放在**kargs前面,否则报语法错误 >>> def kwolf(name,*pargs,**kargs,arts): print(name,pargs,kargs,arts) SyntaxError: invalid syntax
1.2 参数解包模拟python3的print()
描述
python参数解包的*pargs和**kargs以及keyword-only可以模拟python3的print()语句。
使用**kargs时,需要对关键字参数进行校验和解包,而使用keyword-only却不需要。
示例
>>> import sys # get解析关键字模拟python3的print(),多余关键字不报错 >>> def print30(*pargs,**kargs): sep=kargs.get('sep',' ') end=kargs.get('end','\n') file=kargs.get('file',sys.stdout) output='' first=True for arg in pargs: output+=('' if first else sep)+str(arg) first=False file.write(output+end) >>> name='梯阅线条';url='tyxt';des='软件测试开发';arts=9555 >>> print30(name,url,des) 梯阅线条 tyxt 软件测试开发 >>> print(name,url,des) 梯阅线条 tyxt 软件测试开发 >>> print30(name,[url],(des,),sep='...') 梯阅线条...['tyxt']...('软件测试开发',) >>> print(name,url,des) 梯阅线条 tyxt 软件测试开发 >>> print(name,[url],(des,),sep='...') 梯阅线条...['tyxt']...('软件测试开发',) # 多余关键字参数x=1,未报错 >>> print30(name,x=1) 梯阅线条 # keyword-only 模拟python3的print(),多余关键字参数会报错 >>> def print30(*pargs,sep=' ',end='\n',file=sys.stdout): output='' first=True for arg in pargs: output+=('' if first else sep)+str(arg) first=False file.write(output+end) >>> print30(name,url,des) 梯阅线条 tyxt 软件测试开发 >>> print30(name,url=url) Traceback (most recent call last): File "<pyshell#68>", line 1, in <module> print30(name,url=url) TypeError: print30() got an unexpected keyword argument 'url' # pop解析关键字模拟python3的print(),并且对多余关键字进行报错 >>> def print30(*pargs,**kargs): sep=kargs.pop('sep',' ') end=kargs.pop('end','\n') file=kargs.pop('file',sys.stdout) if kargs:raise TypeError('\'%s\' is an invalid keyword argument for print30()' % list(kargs.keys())[0]) output='' first=True for arg in pargs: output+=('' if first else sep)+str(arg) first=False file.write(output+end) >>> print30(name,x=1) Traceback (most recent call last): File "<pyshell#94>", line 1, in <module> print30(name,x=1) File "<pyshell#93>", line 5, in print30 if kargs:raise TypeError('\'%s\' is an invalid keyword argument for print30()' % list(kargs.keys())[0]) TypeError: 'x' is an invalid keyword argument for print30() >>> print(name,x=1) Traceback (most recent call last): File "<pyshell#95>", line 1, in <module> print(name,x=1) TypeError: 'x' is an invalid keyword argument for print()
1.3 python参数解包求最值及交集
描述
通过python的*pargs参数解包,可以编写任意个数的最值,求任意个序列的交集和并集。
示例
# 将全部比较对象收集到pargs,再进行比较 >>> def minA(*pargs): res=pargs[0] for arg in pargs[1:]: if arg<res: res=arg return res # 将第1个对象存放在first,剩余的收集到rest,再进行比较 >>> def minB(first,*rest): for arg in rest: if arg<first: first=arg return first # 将全部比较对象收集到pargs,转换为list,再进行sort排序 >>> def minC(*pargs): tmp=list(pargs) tmp.sort() return tmp[0] >>> minA(12,13,1,29) 1 >>> minB(12,13,1,29) 1 >>> minC(12,13,1,29) 1 # 通用化最值函数 >>> def minmax(comp,first,*rest): for arg in rest: if comp(arg,first): first=arg return first >>> def lessthan(x,y):return x<y >>> def grtrthan(x,y):return x>y >>> minmax(lessthan,12,13,1,29) 1 >>> minmax(grtrthan,12,13,1,29) 29 # 求多个集合的交集和并集 >>> def intersectf(*pargs): res=[] for x in pargs[0]: for other in pargs[1:]: if x not in other:break else: res.append(x) return res >>> def unionf(*pargs): res=[] for seq in pargs: for x in seq: if not x in res: res.append(x) return res >>> s1,s2,s3='tyxa','tjxa','tkxa' >>> intersectf(s1,s2,s3) ['t', 'x', 'a'] >>> unionf(s1,s2,s3) ['t', 'y', 'x', 'a', 'j', 'k']