原始python的高效优美模式匹配

pattern-matching的Python项目详细描述


LicensePyPI version

已从此包中删除的尾调用优化(TCO) 原因如下:

  1. tco易于实现。
  2. 在任何情况下动态地保证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

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java RandomAccessFile:在循环中写入(字节)或写入(字节数组),哪个更有效?   从命令行运行maven+eclipse的java   在java中无法用正则表达式替换字符串   java Eclipse输出字符与键盘键值不同   JavaWeb服务(服务器客户端)。服务器使用外部项目   java试图制作“夜间模式”过滤器   java Box2d加速和限制车轮速度   javascript JQuery DataTable页面长度在第1页之后不受尊重   java如何使用DefaultCellEditor使JT的列只能得到数字,并在点后用两个符号进行四舍五入?   无法在Java中实例化泛型类型实例   java My code在我的代码中出现数组越界异常,但在前两次输入出错后,它将运行并崩溃   字符串的Java代码压缩和解压缩   SpringBootJava。lang.IllegalStateException:无法解析公共组织中的参数[0]。springframework。http。响应<java。lang.Object>   java在安卓中访问容器的子级   为什么Java不能从InputStream正确地重新创建此映像?