PEP634背面图案匹配

pattern-matching-pep634的Python项目详细描述


模式匹配PEP 634

这是一个实现模式匹配的python包,类似于PEP-634的建议。在

安装

使用包管理器pip安装pattern-matching-pep634。在

pip install pattern-matching-pep634

使用

这里有4种不同的模式匹配实现。在

最安全的是:

^{pr2}$

(这是基于PEP-636中的一个例子)

请注意如何指定要使用的名称,以及如何始终使用m.来访问捕获值。 这就是所谓的no_magic实现。这个实现甚至可以在Python3.7和CPython之外的其他实现中工作,这些实现支持与3.7相同的特性

自动查找

{3}你不想使用messing模式,但是你不能使用

frompattern_matching.auto_lookupimportmatchwithmatch(event.get())asm:ifm.case('Click(position=(x, y))'):handle_click_at(m.x,m.y)elifm.case('KeyPress(key_name="Q") | Quit()'):m.game.quit()elifm.case('KeyPress(key_name="up arrow")'):m.game.go_north()elifm.case('KeyPress()'):pass# Ignore other keystrokeselifm.case('other_event'):raiseValueError(f"Unrecognized event: {m.other_event}")

您仍然需要使用m.,但至少不必重复类名并携带Matcher实例。在

请注意,这可能有奇怪的边缘情况,有时会因为某些原因而失败。(最明显的是你认为在函数中可见的内容与实际存在的冲突)

注入

这是为那些不想到处输入m.的人设计的。在

frompattern_matching.injectingimportmatch,casewithmatch(event.get()):ifcase('Click(position=(x, y))'):handle_click_at(x,y)elifcase('KeyPress(key_name="Q") | Quit()'):game.quit()elifcase('KeyPress(key_name="up arrow")'):game.go_north()elifcase('KeyPress()'):pass# Ignore other keystrokeselifcase('other_event'):raiseValueError(f"Unrecognized event: {other_event}")

这将“感染”名称空间并将捕获的名称放入其中。它也会auto_lookup。在

这只适用于Python3.9。它也可能随机中断调试器/覆盖率/跟踪工具。在

请注意,这严重地受到了定义什么是局部变量的问题,例如在哪里查找名称的问题。在

全魔法

这是一个尽可能接近PEP-634中提出的语法的方法

frompattern_matching.full_magicimportmatchwithmatch(event.get()):ifClick(position=(x,y)):handle_click_at(x,y)elifKeyPress(key_name="Q")|Quit():game.quit()elifKeyPress(key_name="up arrow"):game.go_north()elifKeyPress():pass# Ignore other keystrokeselifother_event:raiseValueError(f"Unrecognized event: {other_event}")

(与PEP-634的唯一区别是with match而不是match,if/elif而不是{},而{}而不是{})

这将进行源代码分析,以确定采用何种情况以及哪些名称绑定。这也是Python3.9的唯一版本,可能会与python的任何小版本分离。但这不太可能。在

注意:有时,python所做的少量优化仍然会破坏这一点:

frompattern_matching.full_magicimportmatchwithmatch(n):if1|2:print("Smaller than three")elif3:print("Equal to three")elif_:print("Bigger than three")

Python的peephole优化器(通常)会正确地判断出只有第一个分支可以被执行,而其余的代码则会被丢弃。 这意味着match无法正确跳转到其他行。为了避开优化器,可以添加c@('case')来阻止优化

frompattern_matching.full_magicimportmatchwithmatch(n):ifc@1|2:print("Smaller than three")elifc@3:print("Equal to three")elifc@_:print("Bigger than three")

不必总是这样做,但是如果您收到奇怪的错误消息,这是一个很好的第一次尝试。在

防护装置

保护不是直接实现的,而是通过一个简单的and来支持的,它可以添加到案例中:

frompattern_matching.injectingimportmatch,casewithmatch(p):ifcase('(x, y)')andx==y:print("X=Y, at",x)else:print("Not on a diagonal")

这对所有选项都是类似的

许可证

MIT

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

推荐PyPI第三方库


热门话题
html如何在JavaScript中获取当前Windows用户的名称   用于屏蔽电子邮件的java正则表达式   java Jsoup Android解析   为了避免在运行时缺少Java泛型,将超类型绑定到子类实例   java JTextArea。setText(空);不会释放内存   安卓源Java OutOfMemoryError在构建AOSP 10时出错   java打印到达数组末尾所需的最小跳数序列   使用mvn命令的java Selenium TestNG并行执行   javasocket编程:在关闭服务器之前通知所有客户端   java如何在加载新的安卓片段时显示progressbar?   java从actor系统中删除AKKA actor,并创建另一个具有相同路径名的actor   java我可以用浓缩咖啡做性能测试,还是应该用其他东西?   JavaTreeView(TreeItem)是否可以获取层次结构索引?   带远程服务的java Android应用程序