您一直梦想的python模式匹配
backports.pamp的Python项目详细描述
pampy:python的模式匹配
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])
TAIL
和REST
实际上是相同的意思。
您可以嵌套列表和元组
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'
所有可以匹配的内容
作为模式,您可以使用任何python类型、任何类或任何python值。
运算符_
和内置类型(如int
或str
)提取传递给函数的变量。
类型和类通过instanceof(value, pattern)
匹配。
Iterable
模式通过所有元素递归匹配。字典也一样。
Pattern Example | What it means | Matched Example | Arguments Passed to function | NOT Matched Example |
---|---|---|---|---|
^{ | only the string ^{ | ^{ | nothing | any other value |
^{ | only ^{ | ^{ | nothing | any 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 instance | any other object |
^{ | Any object (even None) | that value | ||
^{ | The same as ^{ | that value | ||
^{ | A tuple made of any two integers | ^{ | ^{ | (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 ^{ | ^{ | ^{ | ^{ |
^{ | Any dict with ^{ | ^{ | ^{ | ^{ |
^{ | Any string that matches that regular expression expr | ^{ | ^{ | ^{ |
^{ | Any Pet dataclass with ^{ | ^{ | ^{ | ^{ |
使用strict=false
默认情况下match()
是严格的。如果没有匹配的模式,则会引发一个MatchError
。
你可以用strict=False
来阻止它。在本例中,match
如果没有匹配的内容,只返回False
。
>>> match([1, 2], [1, 2, 3], "whatever")
MatchError: '_' not provided. This case is not handled: [1, 2]
>>> match([1, 2], [1, 2, 3], "whatever", strict=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'
使用数据类
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>;=3.6Because dict matching can work only in the latest Pythons中工作。
我目前正在为python2开发一个带有一些小语法更改的后台端口。
要安装它:
$ pip install pampy
或者
$ pip3 install pampy