您一直梦想的python模式匹配

pamp的Python项目详细描述


Pampy in Star Wars

pampy:python的模式匹配

License MITTravis-CI StatusCoverage StatusPyPI version

pampy非常小(150行),速度相当快,并且经常使代码更可读 因此更容易推理。There is also a JavaScript version, called Pampy.js

您可以编写许多模式

模式按其出现的顺序进行计算。

你可以写斐波那契

接线员的意思是“我没想到的任何其他案件”。

frompampyimportmatch,_deffibonacci(n):returnmatch(n,1,1,2,1,_,lambdax:fibonacci(x-1)+fibonacci(x-2))

您可以用5行编写lisp计算器

frompampyimportmatch,REST,_deflisp(exp):returnmatch(exp,int,lambdax:x,callable,lambdax:x,(callable,REST),lambdaf,rest:f(*map(lisp,rest)),tuple,lambdat:list(map(lisp,t)),)plus=lambdaa,b:a+bminus=lambdaa,b:a-bfromfunctoolsimportreducelisp((plus,1,2))# => 3lisp((plus,1,(minus,4,2)))# => 3lisp((reduce,plus,(range,10)))# => 45

你能匹配这么多东西!

match(x,3,"this matches the number 3",int,"matches any integer",(str,int),lambdaa,b:"a tuple (a, b) you can use in a function",[1,2,_],"any list of 3 elements that begins with [1, 2]",{'x':_},"any dict with a key 'x' and any value associated",_,"anything else")

您可以匹配[头,尾]

frompampyimportmatch,HEAD,TAIL,_x=[1,2,3]match(x,[1,TAIL],lambdat:t)# => [2, 3]match(x,[HEAD,TAIL],lambdah,t:(h,t))# => (1, [2, 3])

TAILREST实际上是相同的意思。

您可以嵌套列表和元组

frompampyimportmatch,_x=[1,[2,3],4]match(x,[1,[_,3],_],lambdaa,b:[1,[a,3],b])# => [1, [2, 3], 4]

你可以嵌套听写。你可以用u作为钥匙!

pet={'type':'dog','details':{'age':3}}match(pet,{'details':{'age':_}},lambdaage:age)# => 3match(pet,{_:{'age':_}},lambdaa,b:(a,b))# => ('details', 3)

感觉把多个单词放进听写不应该起作用。是不是不保证听写的顺序? 但这是因为 in Python 3.7, dict maintains insertion key order by default

您可以匹配类层次结构

classPet:passclassDog(Pet):passclassCat(Pet):passclassHamster(Pet):passdefwhat_is(x):returnmatch(x,Dog,'dog',Cat,'cat',Pet,'any other pet',_,'this is not a pet at all',)what_is(Cat())# => 'cat'what_is(Dog())# => 'dog'what_is(Hamster())# => 'any other pet'what_is(Pet())# => 'any other pet'what_is(42)# => 'this is not a pet at all'

使用数据类

Pampy支持Python3.7数据类。可以将运算符_作为参数传递,它将匹配这些字段。

@dataclassclassPet:name:strage:intpet=Pet('rover',7)match(pet,Pet('rover',_),lambdaage:age)# => 7match(pet,Pet(_,7),lambdaname:name)# => 'rover'match(pet,Pet(_,_),lambdaname,age:(name,age))# => ('rover', 7)

所有可以匹配的内容

作为模式,您可以使用任何python类型、任何类或任何python值。

运算符_和内置类型(如intstr)提取传递给函数的变量。

类型和类通过instanceof(value, pattern)匹配。

Iterable模式通过所有元素递归匹配。字典也一样。

Pattern ExampleWhat it meansMatched ExampleArguments Passed to functionNOT Matched Example
^{}only the string ^{} matches^{}nothingany other value
^{}only ^{}^{}nothingany other value
^{}Any integer^{}^{}any other value
^{}Any float number^{}^{}any other value
^{}Any string^{}^{}any other value
^{}Any tuple^{}^{}any other value
^{}Any list^{}^{}any other value
^{}Any instance of MyClass. And any object that extends MyClass.^{}that instanceany other object
^{}Any object (even None)that value
^{}The same as ^{}that value
^{}A tuple made of any two integers^{}^{} and ^{}(True, False)
^{}A list that starts with 1, 2 and ends with any value^{}^{}^{}
^{}A list that start with 1, 2 and ends with any sequence^{}^{}^{}
^{}Any dict with ^{} and with an age^{}^{}^{}
^{}Any dict with ^{} and with an ^{} age^{}^{}^{}
^{}Any string that matches that regular expression expr^{}^{} and ^{}^{}
^{}Any Pet dataclass with ^{}^{}^{}^{}

使用默认值

默认情况下match()是严格的。如果没有匹配的模式,它将引发一个MatchError

相反,您可以使用default提供回退值,当没有匹配的内容时使用该值。

>>> match([1, 2], [1, 2, 3], "whatever")
MatchError: '_' not provided. This case is not handled: [1, 2]

>>> match([1, 2], [1, 2, 3], "whatever", default=False)
False

使用正则表达式

pampy支持python的regex。可以将编译后的regex作为模式传递,而pampy将运行patter.search(),然后将.groups()的结果传递给操作函数。

defwhat_is(pet):returnmatch(pet,re.compile('(\w+)-(\w+)-cat$'),lambdaname,my:'cat '+name,re.compile('(\w+)-(\w+)-dog$'),lambdaname,my:'dog '+name,_,"something else")what_is('fuffy-my-dog')# => 'dog fuffy'what_is('puffy-her-dog')# => 'dog puffy'what_is('carla-your-cat')# => 'cat carla'what_is('roger-my-hamster')# => 'something else'

为python3安装

Pampy在python>;=3.6Because dict matching can work only in the latest Pythons中工作。

要安装它:

$ pip install pampy

或者 $ pip3 install pampy

如果你真的必须使用python2

Pampy首先是python3,但是您可以通过manuel barkhau的this backport在python2中使用它的大部分功能:

pip install backports.pampy

frombackports.pampyimportmatch,HEAD,TAIL,_

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

推荐PyPI第三方库


热门话题
Spring Boot Java后端编码的硬代码通用?   java这种洪水填充算法有什么问题?   java将视图类对象作为参数传递给按钮调用的方法(视图)   java如何在Android上的外部类中存储活动的某些部分?   类路径cp./为什么在运行Java时总是必须手动将CWD包含到CP中?   安卓在Java中通过socket高效地发送大int[]   数组之间的java差异。sort()和数组。并行排序()   python Jython作为java游戏的ingame控制台   java如何使不同PC之间的速度(游戏帧率)相同?   在java中为房间分配床位   java如何解决ResultSet关闭后不允许的错误操作   需要等待在加载网页selenium 3.141.5和java 8时找到特定元素   设计模式如何在JAVA中使用带重载的双重分派?   java Android计时器时间表与scheduleAtFixedRate   在jbossportal2的部署阶段出现错误“java.net.SocketException:打开的文件太多”。7.2   调用java axis2 web服务的c#客户端,对象“重置”