Python模式匹配

2021-02-17 18:07:50

此回购包含问题跟踪器,示例和与PEP 622:结构模式匹配有关的早期工作。该提案的当前版本为PEP 634,该指导委员会于2021年2月8日接受了该提案。动机和理由已在PEP 635中进行了编写,而指南则在PEP 636中进行了编写。 636作为附录A.

Brandt Bucher编写的完整参考实现可作为CPython存储库的分支获得。这很容易转换为请求请求。

对于那些不想从源代码构建CPython二进制文件的人,这里有一个Binder游乐场-单击此自述文件顶部的按钮。

match语句采用一个表达式并将其与作为一个或多个case块给出的连续模式进行比较。这在表面上类似于C,Java或JavaScript(以及许多其他语言)中的switch语句,但功能更强大。

def http_error(status):匹配状态:case 400:返回" Bad request"情况401:返回"未经授权"情况403:返回“禁止”情况404:返回"找不到"情况418:将茶壶归还给我情况_:返回“其他”

请注意最后一块:变量名称" _用作通配符,并且永远不会匹配。

#主题是(x,y)元组匹配点:case(0,0):print(" Origin")case(0,y):print(f" Y = {y} ")case(x,0):print(f" X = {x}")case(x,y):print(f" X = {x},Y = { y}")情况_:引发ValueError(" Not a point")

仔细研究那个!第一个模式有两个文字,可以认为是上面显示的文字模式的扩展。但是接下来的两种模式将文字和变量组合在一起,变量从主题(点)捕获值。第四个模式捕获两个值,这使其在概念上与拆箱分配(x,y)= point相似。

如果您使用类来构造数据(例如,数据类),则可以使用类名,后跟类似构造函数的参数列表,但可以捕获变量:

从数据类导入数据类@数据类类Point:x:int y:int def whereis(point):匹配点:case Point(0,0):print(" Origin")case Point(0,y) :print(f" Y = {y}")case Point(x,0):print(f" X = {x}")case Point():print(&# 34; Somewhere else")case _:print(" Not a point")

我们也可以使用关键字参数。以下模式是等效的(并将y属性都绑定到var变量):

模式可以任意嵌套。例如,如果我们有一个点的简短列表,我们可以像这样匹配它:

匹配点:case []:print(" No points")case [Point(0,0)]:print(" The origin")case [Point(x,y)] :print(f"单点{x},{y}")case [Point(0,y1),Point(0,y2)]:print(f" Y轴上的两个{y1},{y2}")情况_:print("其他内容")

我们可以将if子句添加到称为" guard"的模式中。如果后卫为假,则比赛继续进行下一个案件阻止。请注意,值捕获发生在评估防护之前:

匹配点:如果x == y:case Point(x,y):print(f" Y = X at {x}")case Point(x,y):print(f" Not on对角线")

像拆包任务一样,元组和列表模式的含义完全相同,实际上匹配任意序列。一个重要的例外是它们与迭代器或字符串不匹配(从技术上讲,主题必须是collections.abc.Sequence的实例)。

序列模式支持通配符:[x,y,* rest]和(x,y,* rest)的工作方式与解包分配中的通配符相似。 *之后的名称也可能是_,因此(x,y,* _)匹配至少两个项目的序列,而没有绑定其余项目。

映射模式:{"带宽":b,"等待时间":l}捕获"带宽"和"延迟"字典中的值。与sequ​​encepatterns不同,多余的键将被忽略。还支持通配符** rest。 (但是** _将是多余的,因此是不允许的。)

模式可以使用命名常量。这些必须为点分名称,以防止将其解释为捕获变量:

从枚举中导入Enum类Color(Enum):RED = 0 GREEN = 1 BLUE = 2匹配颜色:case颜色。红色:打印(“我看见红色!”)情况颜色。绿色:打印("草为绿色)颜色。蓝色:印刷品("我感觉忧郁:(")

字面值None,False和True受到特殊对待:与主题的比较使用is进行。这:

通过设置类变量__match_args__,类可以覆盖从位置参数到属性的映射。请在PEP中进行了解。