首页 > 其他分享 >Structural Pattern Matching(match 语句)

Structural Pattern Matching(match 语句)

时间:2025-01-08 21:16:20浏览次数:1  
标签:code Pattern screen event cursor Matching match subject

Structural Pattern Matching: 翻译过来应该是 结构化的模式匹配。从python 3.10开始提供了match statement。它远比简单的其它语言中的那种switch语句功能强大的多。
通过一个例子来了解一下这种语句的用法。
假设我们有一个函数,用来区分用户做的操作,并将其打印出来。 我们使用json结构的字符串来做为用户操作的内容并传到这个函数中。目前这个函数只区分用户敲击键盘,及单击鼠标。
下面的函数内部使用if else语句来判断输入的json字符串应该匹配到哪一种用户操作。判断的条件足够的严谨!

import json

def log(event):
    parsed_event = json.loads(event)
    if (
        "keyboard" in parsed_event and
        "key" in parsed_event["keyboard"] and
        "code" in parsed_event["keyboard"]["key"]
    ):
        code = parsed_event["keyboard"]["key"]["code"]
        print(f"Key pressed: {code}")
    elif (
        "mouse" in parsed_event and
        "cursor" in parsed_event["mouse"] and
        "screen" in parsed_event["mouse"]["cursor"]
    ):
        screen = parsed_event["mouse"]["cursor"]["screen"]
        if isinstance(screen, list) and len(screen) == 2:
            x, y = screen
            print(f"Mouse cursor: x={x}, y={y}")
        else:
            print("Unknown event type")
    else:
        print("Unknown event type")


event1 = '''{"keyboard": {"key": {"code": "Enter"}}}'''
event2 = '''{"mouse": {"cursor": {"screen": [600, 900]}}}'''
event3 = '''{"mouse": {"click": {"screen": [600, 900]}}}'''

log(event1)  # Key pressed: Enter
log(event2)  # Mouse cursor: x=600, y=900
log(event3)  # Unknown event type

让我们看一下如果我们使用match statement,如何来改写上面的函数:

import json

def log(event):
    match json.loads(event):
        case {"keyboard": {"key": {"code": code}}}:
            print(f"Key pressed: {code}")
        case {"mouse": {"cursor": {"screen": [x, y]}}}:
            print(f"Mouse cursor: {x=}, {y=}")
        case _:
            print("Unknown event type")


event1 = '''{"keyboard": {"key": {"code": "Enter"}}}'''
event2 = '''{"mouse": {"cursor": {"screen": [600, 900]}}}'''
event3 = '''{"mouse": {"click": {"screen": [600, 900]}}}'''

log(event1)  # Key pressed: Enter
log(event2)  # Mouse cursor: x=600, y=900
log(event3)  # Unknown event type

我们可以明显的看到,实现了同样的判断逻辑,我们使用match语句后,代码非常精简,并且更直观易读。
上面的示例体现了match语句用于匹配数据字典格式数据的能力,就想在场明一个字典的结构以及它要有的某些key和value,并且还可以把我们感兴趣的部分数据方便的提取出来。

现在,假设我们要用一个列表中包含三个值,来表示空间坐标系中的一个点,这个点必须在z轴上,也就是第三个数字为0。 前两个数字可以是float,也可以是int。
下面我们用传统的if...else语句来做一个逻辑严谨的匹配规则判断:

# subject = ['a']  # 匹配不上
# subject = [9.3, 10, 0, 88]  # 匹配不上
subject = [9.3, 10, 0]  # 匹配成功

if isinstance(subject, list) and len(subject) == 3:
    if (
        isinstance(subject[0], int | float) and
        isinstance(subject[1], int | float) and
        subject[2] == 0
    ):
        x, y, _ = subject
        print(f"Point({x=}, {y=})")

# 输出: Point(x=9.3, y=10)

接下来我们用match语句来实现上述匹配规则:

# subject = ['a']  # 匹配不上
# subject = [9.3, 10, 0, 88]  # 匹配不上
subject = [9.3, 10, 0]  # 匹配成功

match subject:
    case list([int() | float() as x, int() | float() as y, 0]):
        print(f"Point({x=}, {y=})")

# 输出: Point(x=9.3, y=10)

标签:code,Pattern,screen,event,cursor,Matching,match,subject
From: https://www.cnblogs.com/rolandhe/p/18660534

相关文章

  • Java设计模式 —— 【行为型模式】命令模式(Command Pattern) 详解
    文章目录模式介绍优缺点适用场景结构案例实现注意事项模式介绍有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。拿订餐来说......
  • 复杂对象的创建与组装 - 建造者模式(Builder Pattern)
    建造者模式(BuilderPattern)建造者模式(BuilderPattern)建造者模式(BuilderPattern)概述建造者模式结构图代码talkischeap,showyoumycode总结建造者模式(BuilderPattern)建造者模式(BuilderPattern)是一种创建型设计模式,它允许你分步骤构建复杂对象。该模式将一个......
  • 你内部啥样跟我没关系 - 迭代器模式(Iterator Pattern)
    迭代器模式(IteratorPattern)迭代器模式(IteratorPattern)迭代器模式概述迭代器模式结构图迭代器模式涉及的角色talkischeap,showyoumycode总结迭代器模式(IteratorPattern)迭代器模式(IteratorPattern)是一种行为型设计模式,它提供了一种方法顺序访问一个聚合对象......
  • CanvasContext.createPattern
    CanvasContext.createPattern(stringimage,stringrepetition)CanvasContext是旧版的接口,新版Canvas2D接口与Web一致从基础库2.9.0开始,本接口停止维护,请使用RenderingContext代替基础库1.9.90开始支持,低版本需做兼容处理。小程序插件:支持相关文档:旧版画......
  • STM32烧写失败之Contents mismatch at: 0800005CH (Flash=FFH Required=29H) !
    一)问题:用ULINK2给STM32F103C8T6下载程序,下载方式设置如下:出现下面两个问题:1)下载问题界面如下:这个错误的信息大概可以理解为,在0x08000063地址上读取到flash存储为FF,但实际上应该写入08H,即校验时读取到数据与实际写入的不符。2)在DEBUG调试的时候,出现如下问题:调试的时候......
  • 【Rust自学】9.2. Result枚举与可恢复的错误 Pt.1:match、expect和unwrap处理错误
    喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)9.2.1.Result枚举通常情况下,错误都没有严重到需要停止整个程序的地步。某个函数之所以运行失败或者是遇到错误通常是由一些可以简单解释并做出响应的原因引起的。比......
  • 架构师-设计模式-享元模式(FlyWeight Pattern)
    享元模式这个名词可能不像其他设计模式一样直接见名知义,可能不像代理模式、单例模式那样一眼看到就知道是干什么的。接下来解释一下享元这个词的含义,享为共享的意思,元就是对象的意思。通俗得来讲享元模式就是共享对象的意思,这种模式一般在系统底层优化使用得比较多,比如前面说过......
  • 从家谱的层级结构 - 组合模式(Composite Pattern)
    组合模式(CompositePattern)组合模式(CompositePattern)组合模式概述组合模式涉及的角色talkischeap,showyoumycode总结组合模式(CompositePattern)组合模式(CompositePattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次关系。组......
  • Java设计模式 —— 【结构型模式】享元模式(Flyweight Pattern) 详解
    文章目录概述结构案例实现优缺点及使用场景概述享元模式也叫蝇量模式:运用共享技术有效地支持大量细粒度的对象;常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建,如果没有我们......
  • nom::sequence::preceded Matches an object from the first parser and discards it,
    nom::sequence::precededMatchesanobjectfromthefirstparseranddiscardsit,thengetsanobjectfromthesecondparser.上面是rustnom官网对于preceded的解释UUUUUUUUU你完全正确,nom::sequence::preceded的定义确实是:Matchesanobjectfromthefirstparse......