原始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第三方库


热门话题
junit有没有办法在Java中重新初始化静态类?   在浏览器中点击应用程序时java Play框架挂起   文件Java错误中的NullPointerException   使用Java中的SNMP查找网络中计算机的登录名   java包装服务器引导程序已弃用,有什么替代方案?   当客户在等待理发时,java信号量值是否存在问题?   java如何使用JavaMail仅下载特定类型的附件   如何在java中将十进制转换为十六进制   java Slick2D粒子系统不会生成粒子   java检测更改事件来自何处   将Java集合类型参数类设置为数组   java如何从eclipse导出为可运行JAR文件?   java EntityManager对象未注入Glassfish和Spring   swing从actionPerformed和actionListener Java返回字符串   java在给定另一个等价键对象的情况下获取映射项的当前键   无论输入如何,java网络都会产生相同的输出