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")
这对所有选项都是类似的
许可证
- 项目
标签: