欢迎访问「Python3分钟」系列。「花3分钟时间」,学习或温习一个Python知识点。今天是第257。
大家好,我是小K。
今天不和大家扯那些高大上的架构和宏大叙事,咱们聊点实际的。
Python3.15的各种预览版动向陆续放出来了,作为一个天天跟代码打交道的搬砖工,我盯着更新日志看了半天,发现官方这次确实听劝,砍掉了很多老掉牙的裹脚布语法,直击我们每天边写代码边骂娘的痛点(好像现在基本的都AI写了?)。
别的虚的不说,今天就盘3个最能让人少掉两根头发的实在变化。
平时写Python脚本,大家是不是习惯性地在开头堆一长串import?
哪怕某个几百兆的大模型或者第三方库,你只在代码最后一行用了一下,Python只要一启动,也会吭哧哧把它们全塞进内存里。
遇到大型 Web 框架或者涉及算法的项目,光是等它启动,就够你去泡杯咖啡了。
这次 3.15 官方直接给加了个lazy关键字:
lazy import numpy as np
lazy from json import dumps
用了 lazy 之后,Python 启动时只是扫一眼,根本不读硬盘。
只有当你的代码真正运行到 np.array() 的那一刻,它才会去动态加载。
这就好比你搬家时,不是一次性把所有大件家具全抬进屋,而是等要睡觉了才把床搬进来。
(是不是有点生成器的味道了?)
对那些需要频繁启动的轻量脚本或大型项目来说,启动速度直接起飞。

我们在写函数或者写 API 接口时,经常需要判断一个很蛋疼的逻辑:
“用户是传了个
None过来,还是压根就没传这个参数?”
如果你把默认值设为 None,那当用户偏偏就想传一个 None 进去时,你的代码就会产生歧义。
为了区分这两种情况,Python官方文档和以往的标准库里,推荐的做法是创建一个独一无二的object实例来当“哨兵值(Sentinel)”:
# 3.15 之前的传统老办法
_MISSING = object()
defget_data(value=_MISSING):
if value is _MISSING:
print("用户真的啥也没传!")
这招虽然能解决歧义,但官方文档自己也吐槽了两个致命缺点:
如果你在代码里 print(_MISSING),或者在 IDE 日志里查看,它永远是一串冷冰冰、看不懂的十六进制内存地址(比如 <object object at 0x102cb4120>)。
静态类型检查工具(如 MyPy)根本不知道这玩意儿是个啥,天天给你代码报警告。
为了干掉这个历史包袱,Python3.15 正式引入了 PEP 661 规范,直接内置了 sentinel() 标准函数。

以后咱们就可以无比优雅地这样写了:
# 3.15 官方正统写法
MISSING = sentinel("MISSING")
defget_data(value=MISSING):
if value is MISSING:
print("用户确实没传参数")
现在,如果你去打印它,屏幕上会清清楚楚输出明明白白的字符串:
MISSING
而且它原生支持静态类型检查,再也不会触发莫名其妙的警告。
这个补丁虽然小,但天天跟复杂接口打交道的人一定懂它有多救命。
这个改动,我甚至觉得它来得太晚了。
以前在 Windows 系统上用 open() 读写文件,如果你是个新手,大概率踩过“中文乱码”的雷,非要在后面手动加上 encoding='utf-8' 才能正常。
这是因为 Windows 还在用那套老掉牙的默认GBK编码。
在3.15里,官方终于统一了标准:全平台默认统一成 UTF-8 编码。

以后再也不用在代码里为了跨平台兼容,到处去补 encoding 参数了。
新手被乱码折磨的历史,到这儿算是彻底终结了。
其实看完这次3.15的更新,我最爽的一点在于,官方终于不再一味去卷那些普通人一辈子用不到几次的边缘特性,而是回过头来,把开发人员每天都在踩的泥潭给顺手排干了。
从 3.15开始,Python 的 Traceback(报错提示)变得越来越有人情味。
如果你在写 Python 列表时,脑子一抽写成了 JavaScript 的 .push(),或者写成了其他语言的习惯,Python3.15 的报错信息不再是冷冰冰的 AttributeError,而是会弹出一行:
“AttributeError: 'list' object has no attribute 'push'.
Did you mean: 'append'?”(你是不是想用 append?)
如果你想加速Python学习,获得专业的指导,30天学会一门技能!
欢迎参加麦叔Python实战训练营,入门营,机器学习营,办公自动化营同步开放。
详情点这里:麦叔Python训练营
如果你希望我更新某个特定小知识,欢迎给我留言。
我是麦叔,聊编程,聊程序员人生。
