page contents

Python 3.15 match 支持一元正号:新手踩坑三年的语法,到底补了什么?

你有没有遇到过这种情况——你兴致勃勃地学 Python 的 match 语句,想用它替代一堆 if/elif,让代码看起来更清爽。你写了一个简单的数字匹配:

attachments-2026-07-ZWQj6vBz6a45c06d7bfe3.png你有没有遇到过这种情况——你兴致勃勃地学 Python 的 match 语句,想用它替代一堆 if/elif,让代码看起来更清爽。你写了一个简单的数字匹配:

def classify(n):

    match n:

        case -1:

            return "负一"

        case +1:

            return "正一"

        case _:

            return "其他"

结果程序直接报错:SyntaxError

你盯着 case +1: 看了半天,心想:正负号不是对称的吗?凭什么 case -1 能跑,case +1 就报错?

这不是你的问题。这是 Python 3.14 及之前版本的一个不对称设计。现在,Python 3.15 把这个坑补上了——match 语句的字面量模式终于支持一元正号

这篇文章,我用大白话讲清楚这个改动到底在补什么,以及新手写 match 时最容易踩的3个坑。

一、match 语句是什么?先补一分钟基础

match 语句是 Python 3.10 引入的结构模式匹配,简单说就是升级版的 switch/case。它不仅能判断值,还能判断结构。

比如你可以这样匹配一个坐标点:

def where(point):

    match point:

        case (0, 0):

            return "原点"

        case (x, 0):

            return "x轴上"

        case (0, y):

            return "y轴上"

        case (x, y):

            return "平面上"

今天我们聊的是 match 里的字面量模式(literal pattern)。它就是用来匹配一个固定值的,比如数字、字符串、None、True、False。

字面量模式里可以写负数,比如 case -1:。这个从 Python 3.10 开始就是合法的。但正号 case +1: 却一直不行。

说白了,Python 在语法层面给负号开了绿灯,却忘了给正号也开一扇门。新手写代码的时候,直觉上觉得 +1 和 -1 应该一样,结果一跑就报错,特别打击人。

二、这个坑有多真实?新手写错不是个别现象

你可能觉得:谁会写 case +1 啊?直接写 case 1 不就行了?

话是这么说,但问题不在于 '需不需要',而在于 '凭什么是语法错误'。

想象一下,你正在教一个新手学 Python。你告诉他:'在 match 里,-1 前面可以加负号。' 他马上问:'那 +1 呢?' 你只能回答:'不行,会报错。' 他再问:'为什么?' 你只好说:'因为 Python 之前没支持。'

这种不对称会让新手对语言产生不信任感。编程语言里最优雅的设计,往往是对称的。+ 和 - 本来就是一对,凭什么一个能写一个不能写?

更实际的问题是,有些代码生成工具或模板会自动在数字前面加符号。比如一个配置解析器,它可能把 '+1' 和 '-1' 都原样输出到 match 模式里。结果 +1 那段代码直接语法错误,逼得你还得写特殊处理逻辑。

还有一种常见场景:你在 case 里想强调符号。比如:

match delta:

    case +1:

        return "增加1"

    case -1:

        return "减少1"

    case 0:

        return "不变"

这种写法对称、可读、好维护。以前 +1 会报错,你只能把 +1 改成 1。虽然结果一样,但代码的对称美感就破坏了。

三、Python 3.15 改了什么?case +1 终于合法了

Python 3.15 的改动很小,但很舒服:match 语句的字面量模式现在接受一元正号

也就是说,下面这些代码在 Python 3.15 里都能正常运行:

def sign_name(x):

    match x:

        case +1:

            return "正一"

        case -1:

            return "负一"

        case 0:

            return "零"

        case _:

            return "其他"

 

print(sign_name(+1))  # 正一

print(sign_name(-1))  # 负一

注意,这个改动只影响字面量模式。它不会改变语义,+1 和 1 在模式里仍然匹配同一个值。它只是让语法更完整、更对称。

从实现角度看,这相当于在语法规则里把 unary_plus 和 unary_minus 一视同仁。以前只认 -1,现在 +1 也走同样的解析路径。

这个改动由 Bartosz Sławecki 贡献,issue 编号是 gh-145239。虽然是一个很小的语法补丁,但它修复的是语言层面的对称性,对教学和代码生成都有实际好处。

四、新手写 match 最容易踩的3个坑

虽然 +1 现在能写了,但 match 语句里还是有不少坑。我挑3个新手最常见的。

坑1:以为 case +1 会匹配 '带正号的整数'

这其实是一个误解。match 里不存在 '带正号' 或 '不带正号' 的整数。+1 和 1 在 Python 里是完全相同的值,模式匹配只看值,不看你怎么写。

match 1:

    case +1:

        print("命中")  # 会命中,因为 +1 == 1

 

match +1:

    case 1:

        print("也命中")  # 同样命中

所以 +1 只是语法上的写法,不是新的匹配类型。别把它当成 '只匹配显式正号' 的模式。

坑2:把一元正号当成表达式模式

match 里有些模式是表达式,有些是字面量。一元正号只能用在字面量模式里,不能用来修饰变量或表达式。

# 这是合法的:字面量 +1

case +1:

 

# 这是不合法的:不能给变量加正号

case +x:

如果你想捕获一个值,应该用变量模式,比如 case x:。如果你还想判断它是正数,可以结合 guard:

match value:

    case x if x > 0:

        print("正数")

    case x if x < 0:

        print("负数")

    case 0:

        print("零")

坑3:case 里写浮点数和复数

match 的字面量模式不支持浮点数。你写 case 3.14: 会报错。这是 Python 3.10 就定下的规则,因为浮点数的精度比较不靠谱。

# 错误!浮点数不能出现在字面量模式

match pi:

    case 3.14:

        ...

如果你需要匹配浮点数,用变量模式加 guard 是最安全的写法:

match pi:

    case x if abs(x - 3.14) < 1e-9:

        print("约等于 3.14")

最后总结一下今天的内容:

1. Python 3.10 起 match 的字面量模式支持 case -1,但不支持 case +1。

2. Python 3.15 把这个不对称补上了,case +1 现在合法。

3. +1 和 1 匹配的值完全相同,没有新增匹配类型,只是语法更对称。

4. 新手写 match 时注意:正号只用于字面量,不能修饰变量;浮点数不能直接出现在 case 里。

这个改动看起来小,但它让 Python 的语言设计更一致。对新手来说,一致性就是最好的老师。

你在写 match 的时候有没有遇到过这种 '明明直觉上应该可以,却偏偏报错' 的情况?评论区聊聊,看看大家还踩过哪些坑。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

2179 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2228 文章
  3. Pack 2179 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章