黑客入侵网站怎么做,河源网站推广,黑马程序员c++笔记,上海有名的设计公司有哪些在Python 3.10中引入的模式匹配语法允许在应用程序中使用强大的新编程技术进行决策。Python虽然功能强大且广受欢迎#xff0c;但长期以来缺乏其他语言中的一种流程控制方式#xff0c;即以一种优雅的方式将一个值与多个可能的条件进行匹配。在C和C中#xff0c;这是通过构造…在Python 3.10中引入的模式匹配语法允许在应用程序中使用强大的新编程技术进行决策。Python虽然功能强大且广受欢迎但长期以来缺乏其他语言中的一种流程控制方式即以一种优雅的方式将一个值与多个可能的条件进行匹配。在C和C中这是通过构造switch/case语句来实现的在Rust中这被称为“模式匹配”。
在Python中传统的实现方式并不优雅。一种方式是编写一系列的表达式。另一种方式是将要匹配的值作为字典的键存储起来然后使用这些值来执行相应的操作例如将函数作为值存储并使用键或其他变量作为输入。在许多情况下这种方式可以很好地工作但构建和维护起来可能会很麻烦使用if/elif/else语句。
在经过多次失败的提案后Python语言创始人Guido van Rossum和其他一些贡献者最近提出的一个提案已被接受将在Python 3.10中引入结构化模式匹配。结构化模式匹配不仅可以执行简单的样式匹配还支持更广泛的用例。
Python结构化模式匹配
结构化模式匹配引入了语句和模式语法到Python中。该语句遵循与if/elif/else相同的基本概述。它接受一个对象对该对象进行一项或多项匹配模式的测试并在找到匹配时执行相应的操作。
match command:case quit:quit()case reset:reset()case unknown_command:print (fUnknown command {unknown_command})每个语句后面都跟着一个要匹配的模式。 在上面的示例中我们使用简单的字符串作为我们的匹配目标但更复杂的匹配也是可能的。事实上结构化模式匹配的主要用例是匹配类型的模式而不是值的模式。Python通过从上到下遍历案例列表来执行匹配。在第一个匹配时Python执行相应块中的语句然后跳到块的末尾并继续执行程序的其余部分。在案例之间没有“穿透”但可以设计逻辑来处理单个块中的多个可能情况。稍后会详细介绍还可以捕获匹配的全部或部分内容并重新使用它。在上面的示例中如果没有匹配成功值将被“捕获”在变量中以便我们可以重新使用它。
用Python结构模式匹配对变量进行匹配
这里有一个需要注意的事项。如果在语句中列出变量名这并不意味着应该对命名变量的内容进行匹配。在case语句中变量用于捕获正在匹配的值。如果想要匹配变量的内容那么该变量必须以点分隔的名称表示就像枚举一样。以下是一个示例
from enum import Enum
class Command(Enum):QUIT 0RESET 1
match command:case Command.QUIT:quit()case Command.RESET:reset()
不必使用枚举任何点分隔的属性名称都可以。但是枚举通常是在Python中执行此操作的最熟悉和惯用的方式。不能通过索引来匹配变量的内容。例如x[0]将被拒绝作为语法错误。
使用Python结构化模式匹配进行多个元素的匹配
与模式匹配最有效的工作的关键不仅仅是将其用作字典查找或if/else链的替代品。它是描述要匹配的结构的方式。通过这种方式可以根据要匹配的元素数量或它们的组合进行匹配。这里是一个稍微复杂一些的例子。在这个例子中用户输入一个命令可选择性地跟着一个文件名。
command input(Command:)
match command.split():case [quit]:quit()case [load, filename]:load_from(filename)case [save, filename]:save_to(filename)case _:print (fCommand {command} not understood)我们依次来看一下这些情况
case [quit]测试我们正在匹配的是否是只包含一个元素的列表该元素是由输入进行拆分得到的字符串quit。case [load, filename]测试第一个拆分元素是否是字符串load并且是否有一个紧随其后的字符串。如果是这样我们将第二个字符串存储在变量filename中并将其用于进一步的操作。case [save, filename]与上述情况类似测试第一个拆分元素是否是字符串save并且是否有一个紧随其后的字符串。如果是这样我们将第二个字符串存储在变量filename中并将其用于进一步的操作。case _这是一个通配符匹配。如果到目前为止没有进行其他匹配它将匹配。请注意下划线变量_实际上不绑定到任何内容该名称用作命令的信号表示该情况是一个通配符。这就是为什么我们在块的主体中引用该变量没有捕获到任何内容。
在Python中结构模式的匹配模式
模式可以是简单的值也可以包含更复杂的匹配逻辑。以下是一些示例
case a匹配单个值a。case [a,b]匹配集合[“a”,“b”]。case [a, value1]匹配包含两个值的集合并将第二个值放入捕获变量value1中。case [a, *values]匹配至少包含一个值的集合。其他值如果有将存储在values中。请注意每个集合中只能包含一个星号项就像在Python函数中的星号参数一样。case (a|b|c)使用括号运算符()可以在单个块中处理多个情况。在这里我们匹配a、b或c。case (a|b|c) as letter与上述情况类似只是现在将匹配的项放入变量letter中。case [a, value] if 仅当表达式为真时才匹配捕获。可以在表达式中使用捕获变量。例如如果我们使用value in valid_values则只有在捕获的值实际上在集合valid_values中时才会匹配。case [z, _]以z开头的任何项集合都会匹配。
使用Python结构化模式匹配对对象进行匹配
Python结构化模式匹配系统最高级的功能是能够针对具有特定属性的对象进行匹配。考虑一个应用程序我们正在处理一个名为data的对象我们希望将其转换为文件并从函数中返回。
match media_object:case Image(codecjpg):# Return as-isreturn media_objectcase Image(codecpng) | Image(codecgif):return render_as(media_object, jpg)case Video():raise ValueError(Cant extract frames from video yet)case other_type:raise Exception(fMedia object {media_object} of type {codec} cant be handled yet)在上述每种情况中我们都在寻找特定类型的对象有时还具有特定的属性。第一个情况匹配具有属性image_codec设置为jpg的对象。第二个情况匹配如果type是png或gif。第三个情况匹配任何类型为Video的对象无论其属性如何。最后一个情况是我们的通配情况如果其他情况都不匹配它将捕获所有对象尽管我们使用了一个实际的名称来捕获它而不是使用_。我们还可以在对象匹配中进行捕获
match media_object:case Image(codecmedia_type):print (fImage of type {media_type})有效地使用Python结构模式匹配
Python结构化模式匹配的关键是编写能够覆盖所要匹配的结构情况的匹配。对常量进行简单的测试是可以的但如果只是这样做那么简单的字典查找可能是一个更好的选择。结构化模式匹配的真正价值在于能够根据对象的模式进行匹配而不仅仅是一个特定的对象或一组对象的选择。另一个重要的事情是要记住匹配的顺序。你首先测试哪些匹配将对整体匹配的效率和准确性产生影响。大多数构建了长链的人会意识到这一点但由于潜在的复杂性模式匹配要求你更加仔细地思考顺序。将最具体的匹配放在最前面将最一般的匹配放在最后。最后如果你的问题可以用简单的链式结构或字典查找来解决那么请使用它模式匹配是强大的但并不是万能的。在解决问题时请根据问题的特点选择最合适的方法。
作者Serdar Yegulalp
更多技术干货请关注公众号“云原生数据库”
squids.cn目前可体验全网zui低价RDS免费的迁移工具DBMotion、SQL开发工具等。。