原始python的高效优美模式匹配
pattern-matching的Python项目详细描述
已从此包中删除的尾调用优化(TCO) 原因如下:
- tco易于实现。
- 在任何情况下动态地保证tco都非常昂贵。
如果您确实想在python中使用tco,请检查 https://zhuanlan.zhihu.com/p/42684997。
文档已迁移到自述文件:
文档
这些都是你需要进口的。
frompattern_matchingimportvar,_,T,t,when,Match,overwrite
类型匹配
@when(var[T==int])# T means the type would be capture.deff(v,type_of_v):print(v,type_of_v)f(1)# => (1, int)
备注:使用Match类似于when/overwrite:
m=Match(1)res=m.case(var[T==int])ifres:[a,b]=res.getassert[a,b]==[1,int]
如果模式匹配,Match.case返回一个Result对象。
classResult:__slots__='get'def__init__(self,_):self.get=_
否则返回是None。
值匹配
@when(_==1)deff():return12@when(_==2)deff():return0@when(var)deff(arg):returnarg**3f(1),f(2),f(3)# => 12, 0, 27
类型的通配符
@when(var[t==float])# the lowercase, "t", which indicates that the type just be matched without capture.deff(v):print(v)f(1.0)# => 1.0
值的通配符
@when(_)deff():return1f(1)==f("...")==f(1e-3)# => True
类型边界
classMyList(list):passfromcollectionsimportIterable@when(var[Iterable<=T<=MyList].when(lambdax:1inx))deff(x,T):return(x,T)f([1,2,3])# => ([1, 2, 3], list)f({1,2,3})# => UnsolvedCase: No entry for args<({1, 2, 3},)>, kwargs:<{}>
重载函数
重载函数是通过以下简单情况引入的:
@overwrite(_==[])defsummary():return0@when([var[int],*(_==[])])defsummary(head):returnhead@when([var[int],*var[list]])defsummary(head,tail):returnhead+summary(tail)summary([1,2,3])# => 6
注意,上面的代码毫无用处,因为它不使用尾部调用 优化。
接头类型
@when(var[(t==int)|(t==str)])defdisp(x):print(x)disp(1)# => 1disp('1')# => '1'
交叉口类型
classA:passclassB:passclassC(A,B):pass@when(_[(T==A)|(T==B)])defdisp(ty):print(ty)disp(C())# => <class __main__.C>
差异类型
classA:passclassB:passclassC(A,B):pass@when(_[T!=A])defdisp(ty):print(ty)disp(C())# => <class __main__.C>disp(B())# => <class __main__.B>disp(A())# => UnsolvedCase: No entry for args<(<__main__.A object at ...>,)>, kwargs:<{}>
键入合同
您可以对pattern_matching.T/t应用.when(predicate)方法。
以避免子类化。
classA:passclassB:passclassC(A,B):pass@overwrite(_[T.when(lambda_:notissubclass(_,A))])defdisp(ty):print(ty)disp(C())# => <class __main__.C># => UnsolvedCase: No entry for args<(<__main__.C object at ...>,)>, kwargs:<{}>
匹配参数编号
@when(var/2)deff(g):returng(1,2)f(lambdaa,b:a+b)# => 3f(lambdaa,b,c:a+b)# => UnsolvedCase: No entry for args<(<function <lambda> at ...>,)>, kwargs:<{}>classF:defapply(self,arg):returnarg+1@when(var/1)deff2(g):returng(1)f2(lambdaa,b:a+b)# => UnsolvedCase: No entry for args<(<function <lambda> at ...>,)>, kwargs:<{}>f2(F().apply)# => 2