最近发布的 Python 3.10 中的 Match-Case,其实没那么简单
共 3400字,需浏览 7分钟
·
2021-11-12 15:47
最近发布的 Python 3.10 的所有主要新特性中最重要就是 Match-Case 语法。
有些人仍然认为 Python 不需要“switch-case”语法。甚至 Guido 本人也不支持在 Python 中添加这种语法。但是,为什么它仍然在这个新版本中发布?在我看来,原因可以从名称中找到,它被称为“match case”而不是像大多数编程语言那样的“switch case”。
在本文中,我将使用 7 个示例来演示新语法的灵活性和“pythonic”,希望它能帮助你更容易理解它。如果你对 Python 3.10 中的其他功能感兴趣,可以查看之前的文章,喜欢本文点赞支持,欢迎文末加群畅聊。
1. 基础
在任何花哨的东西之前,让我们从这种新语法的基本用例开始。假设我们正在编写一些代码来将 HTTP 状态代码转换为错误消息,我们可以使用 match-case 语法如下:事实上,对于这个特定的例子,match-case 没有比 if-else 语法带来任何好处,如下所示。
def http_error(status):
if status == 400:
return "Bad request"
elif status == 401:
return "Unauthorized"
elif status == 403:
return "Forbidden"
elif status == 404:
return "Not found"
else:
return "Unknown status code"
如果它只能做这样的事情,我认为它不会被添加。让我们继续用更多的例子来看看它可以有多大的灵活性。
2. 默认情况
它的意思是类似于大多数其他语言中的 switch-case 语法,因此它必须具有“默认情况”。当没有定义的 case 可以匹配时,将执行“default case”中的代码。
Python以其风格实现了这一要求。它使用代表匿名变量的下划线“_”。基本原理是匿名变量可以“匹配”任何东西。让我们看看下面的例子。在上面的代码中,我们添加了默认情况并显示“其他错误”。
3. 合并案例
如果有时我们有多个案例需要合并怎么办?换句话说,这些是不同的情况,但我们处理它们的方式应该是相同的。
在 Python 中,我们可以使用管道“|” 将这些案例合并为一个案例。它也被视为“或”关系。在上面的代码中,我们将 401 和 403 错误都视为身份验证问题,因此我们可以将它们组合到匹配案例中。
4. 列表中的通配符
更有趣的事情来了。假设我们正在使用 match-case 语法编写告警逻辑。它接受一个列表作为参数。第一个元素是时间。比如有“早上”、“下午”和“晚上”,第二个元素是我们需要做的动作。
但是,我们可能希望告警提醒我们同时做多件事。因此,我们希望在列表中传递多个动作,以便告警可以提醒我们将所有动作一一执行。这是实现这种要求的代码。在这个例子中,我们只有两种情况。第一种情况不需要过多解释,因为它只是试图匹配单一动作的情况。在第二种情况下,我们在变量“actions”前面放了一个星号,这样它就可以匹配列表中的一个或多个动作!
5. 子模式
有时,我们可能希望在模式中包含模式。具体来说,我们希望匹配案例将流分类为特定的“案例”。但是,在该模式中,我们想要添加更多限制。
还记得我们已经定义了一天中的“时间”必须是“早上”、“下午”或“晚上”吗?让我们将此限制添加到匹配案例代码中。如果“时间”与这 3 项中的一项不匹配,则告诉用户该时间无效。在上面的代码中,它表明我们可以使用一对括号将我们想要匹配的“模式”括起来,并使用管道来分隔这些模式。如果它不匹配给定的 3 个“时间”之一,则将执行默认情况。
为什么那里有一个问号?我故意添加它是因为我想强调解决方案。通常,匹配子模式之一然后引用它完全匹配的模式并不容易。但是,我们可以在 Python 中拥有这个“参考”。
让我们添加一个“as”关键字,后跟一个变量,这个变量将作为引用。
6. 条件模式
我们需要让这个告警更加“智能”。到了晚上,让我们显示一些消息来感谢用户完成一天的工作。因此,我们在上面的代码中又添加了一个 case 来只匹配“evening”。让我们让这个警报更加智能,以鼓励用户“工作与生活平衡”。因此,当用户晚上想工作或学习时,闹钟会建议用户休息一下。
7. 匹配对象
到目前为止,我们已经探索了很多, 我猜你可能有这样的感觉,它是“match-case”而不是“switch-case”,因为“pattern”永远是关键。
让我们有一个更复杂的例子。是的,让我们使用 match-case 来匹配一个对象。
我编一个简单的用例。创建了一个名为“Direction”的类,用于保持水平(东或西)和垂直(北或南)轴上的方向。
class Direction:
def __init__(self, horizontal=None, vertical=None):
self.horizontal = horizontal
self.vertical = vertical
现在,我们要使用 match-case 语法来匹配来自此类的实例并根据属性显示一条消息。
def direction(loc):
match loc:
case Direction(horizontal='east', vertical='north'):
print('You towards northeast')
case Direction(horizontal='east', vertical='south'):
print('You towards southeast')
case Direction(horizontal='west', vertical='north'):
print('You towards northwest')
case Direction(horizontal='west', vertical='south'):
print('You towards southwest')
case Direction(horizontal=None):
print(f'You towards {loc.vertical}')
case Direction(vertical=None):
print(f'You towards {loc.horizontal}')
case _:
print('Invalid Direction')
然后,让我们从类中创建一些对象进行测试。
d1 = Direction('east', 'south')
d2 = Direction(vertical='north')
d3 = Direction('centre', 'centre')
结果表明,match-case 可以根据这些对象的属性轻松匹配这些对象!
总结
在本文中,我介绍了 Python 3.10 中引入的新语法“match-case”,以及它是多么灵活和强大。我相信掌握这种新语法将有助于我们在可读性方面编写更好的代码。
长按或扫描下方二维码,后台回复:加群,可申请入群。一定要备注:入群+地点+学习/公司。例如:入群+上海+复旦。
感谢你的分享,点赞,在看三连