• Python居然开始抄作业了,这次抄的是Rust


    整个九月份,我都在忙一个js的项目。因为好多年不写js,动手之前特地找了一些js的资料恶补半天,结果发现js越来越像Python了。且不说js从基于原型的面向对象转向了基于类的面向对象,单是类型化数组(Typed Arrays)的引入,就让用惯了NumPy的我喜出望外。另外,js的数组推导式和装饰器,也几乎是完全照抄了Python的作业。

    进入十月,Python社区指导委员会正式推出了Python3.10,距离上一个版本发布,正好过去了一年。记得Python3.9发布之后没几天,我写过一篇名为《危险的转变:Python正在从简明转向臃肿,从实用转向媚俗》的博文,着实吐槽了一番,正所谓爱之也深恨之也切。这次新版本发布,我自然不会放过尝鲜的机会,赶紧安装尝试了一下,却发现,一向特立独行的Python居然开始抄作业了,这次抄的是Rust

    众所周知,Rust有两样镇山之宝,一是安全的内存模型,二是模式匹配。在内存管理上,Python使用了传统的垃圾回收的内存模型,和Rust没有多少可比性。随着Python3.10的发布,模式匹配被引入到Python中,而且几乎是完全照搬了Rust的概念。 Rust支持模式匹配中的变量绑定、结构体/元组解构、守卫条件判断、数值范围匹配等特性,Python照单全收,连下划线 _ 匹配任意情形也原封不动地继承了过来。

    让我们一起来揭开Pyhton3.10最重要的升级——模式匹配的盖头。

    类似C语言的switch case, Python的模式匹配最简单的应用就是对字面值进行匹配:

    >>> a = 3
    >>> match(a):
        case 1:
            print("a == 1")
        case 2:
            print("a == 2")
        case _:		# default
            print("other")
            
    other
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    case语句中,支持或操作:

    >>> import datetime
    >>> n = datetime.datetime.now()
    >>> match(n.weekday()):
        case 0|1|2|3|4: print("工作日")
        case 5|6: print("周末")
            
    工作日
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    除了字面值外,case语句,支持对上面提到的模式进行解构,如对元组

    >>> a = (0, 1)
    >>> match(a):
        case (0, y):  # 匹配所有第0个元素是0的元组
            print(f"a[0]==0, a[1]=={y}")
        case (x, 0):  # 匹配所有第1个元素是0的元组
            print(f"a[1]==0, a[0]=={x}")
            
    a[0]==0, a[1]==1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对列表:

    >>> cmd = "ls test"
    >>> match(cmd.split()):
        case ["ls", path]: print(f"显示{path}中的文件和目录")
        case ["rm", path]: print(f"删除{path}中的文件和目录")
        case ["cp", src, dest]: print(f"将{src}复制到{dest}")
            
    显示test中的文件和目录
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    对字典:

    >>> a = {"name": "xxx", "age": 40, "job": "程序员"}
    >>> match(a):
        case {"name": name, "age": age, "job": "程序员"}:
            print(f"他是一名程序员,名字叫{name}, {age}岁了")
        case {"name": name, "age": age, "job": "教师"}:
            print(f"他是一名人民教师,名字叫{name}, {age}岁了")
    
    他是一名程序员,名字叫xxx, 40岁了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    对于类对象,match case照样可以使用如:

    >>> class Point():
        def __init__(self,x,y):
            self.x = x
            self.y = y
            
    >>> a = Point(1, 2)
    >>> match(a):
        case Point(x=1, y=y): print(f"这是一个X坐标为1的点,它的Y坐标为{y}")
        case Point(x=x, y=2): print(f"这是一个Y坐标为2的点,它的X坐标为{x}")
            
    这是一个X坐标为1的点,它的Y坐标为2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    也可以用于多个类:

    >>> class Programmer:
        def __init__(self, lang):
            self.lang = lang
    
            
    >>> class Teacher:
        def __init__(self, subject):
            self.subject = subject
            
    >>> a = Programmer("Python")
    >>> match(a):
        case Programmer(lang="Python"): print("咱们都是Pyhon程序员!")
        case Programmer(): print("原来你也是一名程序员!")
        case Teacher(): print("向人民教师致敬!")
            
    咱们都是Pyhon程序员!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    case 语句后,还支持添加一个if语句,进一步对匹配的条件进行限制,这个if语句,被称之为“守卫”。如:

    >>> class Point():
        def __init__(self,x,y):
            self.x = x
            self.y = y
    
            
    >>> a = Point(2,2)
    >>> match(a):
        case Point(x=x, y=y) if x==y: print("这个点在斜率为1的直线上")
        case Point(x=x, y=y) if x==-y: print("这个点在斜率为-1的直线上")
            
    这个点在斜率为1的直线上
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    美中不足的是,我没有找到case语句中直接使用范围的方法,但这个可以用守卫来解决:

    >>> a = 5
    >>> match(a):
        case x if 1 <= x < 10: print("数字在1和10之间")
        case x if 10 <= x < 20: print("数字在10和20之间")
            
    数字在110之间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    怎么样?盖头之下的模式匹配是不是Rust家的那位小姑娘呢?

  • 相关阅读:
    【案例分享】H3C交换机堆叠配置
    深入理解Linux网络技术内 幕(六)——PCI层和网络接口卡
    Redis中的数据类型及与Mysql数据库同步方法
    [flink]部署模式
    快速掌握Reactor Core实现响应式编程
    Ubuntu QtCreator不能输入中文,可以从其他位置复制中文
    华为机试 - 发广播
    2、图机器学习——Graph Embedding
    CSMM软件能力成熟度评估
    【蓝桥杯选拔赛真题30】python计算倒数和 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
  • 原文地址:https://blog.csdn.net/xufive/article/details/120927757