刚刚,Python3.10正式发布了!我发现了⼀个可怕的功能...
就在前⼏天( 2021年10⽉4⽇) Python 终于正式发布了 3.10 版本,看了下这个版本的⼀些特性,最受关注的应该就是结构模式匹配了吧?也就是⼤家所熟悉的 switch-case ,写错了不好意思,是 match-case。
下边是最简单的⼀个 match-case 的例⼦,看起来是不是⾮常的直观简洁?
def http_error(status):
match status:
case 400:
print("Bad request")
case 404:
print("Not found")
case 418:
print("I'm a teapot")
case _:
print("Something's wrong with the internet")
对这个功能满怀期待的我,赶紧就下载升级了 3.10 的 Python 赶紧试⽤,可没想到在我深⼊的体验过后,我从最开始的期待,变成了敬畏。
敬畏,是因为这样⼀个看似简单的新功能,却有着不少的学习成本,并且对结构模式匹配半知半解的⼈来说,会增⼤代码出错的概率,并不是⼤数⼈都能轻松驾驭的。
我为什么会这么说呢?我会在⽂章最后来简述我的观点。
鉴于⼤多数⼈,都没有实际⽤过这种结构模式匹配,我会从升级 3.10 开始教⼤家如何尝鲜这个新功能,然后我会详细的介绍 match-case 的使⽤⽅法。
1. 升级 3.10 新版本
我本机的电脑上⽬前的 Python 版本是 3.9.1 的
$ /usr/local/bin/python3 --version
Python 3.9.1
由于这边我使⽤的是 mac,因此我从官⽹上下载的是 Python 3.10 的 pkg ⽂件,如果是 win 的⽤户,可以下载相应的 msi 或者 exe ⽂件。
下载链接我贴在下边,可以直接访问下载
mac: /ftp/python/3.10.0/python-3.10.0-macos11.pkg
win: /ftp/python/3.10.0/python-3.
我下载好安装⽂件后,双击安装,之后就双击下载的 pkg ⽂件,进⼊安装流程
⼀路点击继续,该同意的同意⼀下,出现如下提⽰表⽰安装成功。
再次在终端上确认下是否升级成功
2. or 模式的使⽤
在上⾯我已经贴出⼀个 match-case 的最简单⽰例,这边就直接跳过简单⽰例,来说说那些⽐较特殊的⽤法。
在 Python 3.10 中其实有新增⼀个联合类型操作符|,但这个只能⽤于类型,具体的⽤法,我会在下⼀篇⽂章中做详细的介绍,本篇⽂章还是集中于 match-case 的使⽤。
在学习match-case 的时候,你会发现,也有⼀个类似于联合类型操作符的⽤法,但请你要注意区别,它并不是联合类型操作,⽽是在 match-case 下独有的 or模式操作符|,它可以将多个具体相同逻辑的 case 语句简写成同⼀个
match status:
case 401 | 403 | 404:
print("Not allowed")
case _:
print("Something's wrong with the internet")
3. 通配符匹配任意对象
match-case 的出现有利于提⾼代码的可读性,让你的代码更加优雅,但同时要使⽤好它,也是有⼀些门槛的,特别是通配符的使⽤。
下边我举⼀些例⼦来进⾏讲解
在如下代码中,使⽤了通配符_和可变参数中的*符号
import sys
match sys.argv[1:]:
case ["quit"]:
print("exit")
case ["create", user]: # 创建单个⽤户
print("create", user)
case ["create", *users]: # 批量创建多个⽤户
for user in users:
print("create", user)
case _:
print("Sorry, I couldn't understand the argv")
最后⼀个 case 中的_并不作为变量名,⽽表⽰⼀种特殊的模式,在前⾯的 case 中都未命中的情况下,该 case 会是最后的保障,能确保命中,它相当于 Go 语⾔中的default分⽀。
import "fmt"
func main() {
education := "本科"
switch education {python安装教程非常详细
case "博⼠":
fmt.Println("我是博⼠")
case "研究⽣":
fmt.Println("我是研究⽣")
case "本科":
fmt.Println("我是本科⽣")
case "⼤专":
fmt.Println("我是⼤专⽣")
default:
fmt.Println("学历未达标..")
}
}
4. 使⽤可变参数 *ar g s
第⼆个 case 和第三个 case ⾮常的像,区别在于第三个 case中users前加了个*,他跟原 Python 函数中的可变参数是⼀个⽤法,会匹配列表的多个值。
在该中表⽰可以从命令⾏参数中批量创建⽤户。
在 match-case 中相应的 case 若有运⾏到,对应的变量是会被创建的。⽐如
5. 使⽤可变参数 **kv
在如下代码中,**rest会匹配到所有的 args 中的 key 和 value
6. 长度的匹配⽅式
若你希望使⽤ case 仅对对象的长度做⼀些匹配,可以使⽤下⾯这样的⽅式
[*_]匹配任意长度的list;
(_, _, *_)匹配长度⾄少为 2 的tuple。
7. 类对象的匹配
对于类对象的匹配,下边这个例⼦⾜够简单,不再讲解。
8. 匹配要注意顺序
在上边基本介绍完了 match-case 的使⽤⽅法,如需更详细的内容,不如去通读下的内容。
在⽂章最开始的时候,我说过开发者应该对这些新特性⼼存敬畏,match-case 这样⼀个看似简单的新功能,却有着不少的学习成本,如果对结构模式匹配半知半解的⼈来说,可能会增⼤代码出错的概率,并不是⼤数⼈都能轻松驾驭的。
之所以会这么说,是因为 match-case 在⾯对不同的对象,它的匹配的规则也有所不同。
当 match 的对象是⼀个 list 或者 tuple 的时候,需要长度和元素值都能匹配,才能命中,这就是为什么下⾯这个例⼦⾛的是第三个case ⽽不是第⼆个 case。
当 match 的对象是⼀个 dict 的时候,规则却有所不同,只要 case 表达式中的 key 在所 match 的对象中有存在,即可命中。
⽽当 match 的对象是类对象时,匹配的规则是,跟 dict 有点类似,只要对象类型和对象的属性有满⾜ case 的条件,就能命中。
因此在写 match-case 的时候,最⼤的难点可能就是如何把握这个顺序,才能确保你写的代码不会翻车。
我个⼈总结⼀些规律,仅供⼤家参考:
list 或者 tuple:应该从不格式到严格
dict 或者 object:应该从严格到不严格
在经过半天时间的尝鲜后,我有了⼀些⾃⼰的理解,分享给⼤家,不知道我的理解有没有问题,但我依然建议⼤家在充分了解 match-case 的匹配规则后,再去使⽤它。
另外,这个功能⼀出,有许多⼈表⽰终于来了,也有⼀些⼈表⽰太鸡肋了。
我对于此事的看法是,match-case 必然有⼀定的适⽤场景,但这不意味着 match-case 是必要的,所有的 match-case 都可以换成 if 表达式,但反过来却不然,if 可以结合 and 和 or 承接 n 个多复杂的组合判断,但 match-case 却不⾏,它只能⽤于单个对象进⾏匹配判断。
但是从⼀定程度上来说,它有点多余,⽽且有⼀定的上⼿成本。
那么对于这样的⼀个新特性,你会⽤它吗?
⽂章最后给⼤家介绍三个我⾃⼰写的在线⽂档:
第⼀个⽂档:
花了两个多⽉的时间,整理了 100 个 PyCharm 的使⽤技巧,为了让新⼿能够直接上⼿,我花了很多的时间录制了上百张 GIF 动图,有兴趣的前往在线⽂档阅读。
第⼆个⽂档:
系统收录各种 Python 冷门知识,Python Shell 的多样玩法,令⼈疯狂的 Python 炫技操作,Python 的超详细进阶知识解读,⾮常实⽤的 Python 开发技巧等。
第三个⽂档:
花了三个⽉时间写的⼀本适合零基础⼊门 Python 的全中⽂教程,搭配⼤量的代码案例,让初学者对代码的运作效果有⼀个直观感受,教程既有深度⼜有⼴度,每篇⽂章都会标内容的难度,是基础还是进阶的,可供读者进⾏选择,是⼀本难得的 Python 中⽂电⼦教程。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论