整个九月,忙着做一个js项目。因为很多年没写js了,开始之前找了很久js的资料,发现js越来越像Python了。更不用说js已经从基于原型的面向对象转变为基于类的面向对象。光是类型化数组(TypedArrays)的引入就让用惯了NumPy的我大吃一惊。另外,js的数组推导和装饰器,几乎是完全照抄Python的功课。进入10月,Python社区指导委员会正式推出Python3.10,距上一版本发布整整一年。记得在Python3.9发布后的几天,我写了一篇名为《危险的转变:Python正在从简明转向臃肿,从实用转向媚俗》的博文,真心吐槽一下,正所谓爱之深恨之深。这次出新版本,自然不会放过试用的机会,赶紧装上试试,结果发现一向特立独行的Python开始抄作业了,这次复制Rust。众所周知,Rust有两大宝,一是安全内存模型,二是模式匹配。在内存管理方面,Python采用传统的垃圾回收内存模型,与Rust没有多少可比性。随着Python3.10的发布,模式匹配被引入Python,几乎完全照搬了Rust的概念。Rust在模式匹配中支持变量绑定、结构/元组解构、守卫条件判断、取值范围匹配等特性。Python统统接受,甚至匹配任何情况的下划线_也被原封不动地继承。下面来揭开Pyhton3.10最重要的升级——模式匹配的头巾。类似于C语言中的switchcase,Python模式匹配最简单的应用就是匹配字面值:>>>a=3>>>match(a):case1:print("a==1")case2:print("a==2")case_:#defaultprint("other")othercase语句支持或操作:>>>importdatetime>>>n=datetime.datetime.now()>>>match(n.weekday()):case0|1|2|3|4:print("weekday")case5|6:print("weekend")除了文字值,case语句还支持上述模式的解构。如元组:>>>a=(0,1)>>>match(a):case(0,y):#匹配所有第0个元素为0的元组print(f"a[0]==0,a[1]=={y}")case(x,0):#匹配所有首元素为0的元组print(f"a[1]==0,a[0]=={x}")a[0]==0,a[1]==1对列表:>>>??cmd="lstest">>>match(cmd.split()):case["ls",path]:print(f"显示{path}中的文件和目录")case["rm",path]:print(f"删除{path}中的文件和目录")case["cp",src,dest]:print(f"Copy{src}to{dest}")在测试中显示文件和目录对的字典:>>>a={"name":"xxx","age":40,"job":"Programmer"}>>>垫子ch(a):case{"name":name,"age":age,"job":"programmer"}:print(f"他是程序员,名字叫{name},{age}岁")case{"name":name,"age":age,"job":"teacher"}:print(f"他是人民教师,名字叫{name},{age}岁")他是程序员,他叫xxx,今年40岁。对于类对象,仍然可以使用matchcase,如:>>>classPoint():def__init__(self,x,y):self.x=xself.y=y>>>a=Point(1,2)>>>match(a):casePoint(x=1,y=y):print(f"这是一个点,X坐标为1,Y坐标为{y}")casePoint(x=x,y=2):print(f"这是一个Y坐标为2的点,它的X坐标为{x}")这是一个X坐标为1的点,它的Y坐标为2也可以用于多类:>>>classProgrammer:def__init__(self,lang):self.lang=lang>>>classTeacher:def__init__(self,subject):self.subject=subject>>>a=Programmer("Python")>>>匹配(a):caseProgrammer(lang="Python"):print("我们都是Python程序员!")caseProgrammer():print("原来你也是程序会员!")caseTeacher():print("向人民的老师!”)我们都是Python程序员!在case语句之后,也支持添加if语句进一步细化匹配条件行限制,这个if语句,被称为“守卫”,例如:>>>classPoint():def__init__(self,x,y):self.x=xself.y=y>>>a=Point(2,2)>>>match(a):casePoint(x=x,y=y)ifx==y:print("这个点在一条斜率为1的直线上")casePoint(x=x,y=y)ifx==-y:print("这个点在一条斜率为-1的直线上")美中不足的是这个点在一条斜率为1的直线上,我没有't找到了在case语句中直接使用range的方法,不过这个可以守着解决:>>>a=5>>>match(a):casexif1<=x<10:print("数字介于1and10")casexif10<=x<20:print("数字在10和20之间")1和10之间的数字
