最近我们终于全线升到了 py39/go117,
在大家对 go 新特性兴奋之余,
@ackerr 提了一个很犀利的问题:
“Python 新版本都更新了啥?”
确实,
除了 f-strings/dataclasses 这种大家可能熟知的功能,
新的版本究竟更新了什么呢?
以前 dota 一个小版本的 changelog 都能读的津津有味的我,
今天决定咀嚼一遍从 py36 至 py310 的更新日志 (HOHO
以下代码片段都可以在最新的 Python 3.10.0 Repl 中执行。
What’s new in Python 3.6
Python 3.6 是在 2016-12-23 发布的,官方维护至 2021-12-23。
感知比较大的几个改动包括:
# 字符串拼接中,支持使用 f-strings 的 inline 拼接方法
# 终于能像 JS 那样方便地进行字符串拼接了
name = "ackerr"
precision = 2
height = 183.2
assert f"{name} is {height:0.{precision}f}cm tall." == "ackerr is 183.20cm tall."
# 常数定义中,可以使用下划线增加可阅读性
number = 3_735_928_559
magic = 0xDEAD_BEEF
assert number == magic
# 变量定义中,支持类型声明了
# 值得注意的是 Python 依旧不是强类型,只是写在了 __annotations__ 这个变量里
import typing
numbers: typing.List[int] = [1,1,4,5,1,4]
complex_data: typing.Dict[int, typing.Set[int]] = {}
assert "complex_data" in __annotations__
# 加了一个 enum.auto 的函数,开发者不用费心去自增了
import enum
class Colors(enum.Enum):
R = enum.auto()
G = enum.auto()
B = enum.auto()
assert Colors.B.value == 3
其它的一句话更新包括:
- Windows 上默认编码都设定为
utf-8
. - 修改了 dict 的实现,使其内存占用量比 py35 下降了 25%.
- 标准包
asyncio
更新了一大串功能,使其变得能用了.
What’s new in Python 3.7
Python 3.7 是在 2018-06-27 发布的,官方维护至 2023-06-27。
感知比较大的几个改动包括:
# 类型系统支持惰性求值了,可以不需要用字符串来指代自己了
from __future__ import annotations
class QuerySet:
def filter(self, **params) -> QuerySet:
"""some database filter"""
# 新增了 dataclass 标准包
# 相比于 dict 传参大大优化了可读性
import dataclasses as dc
@dc.dataclass
class Person:
name: str
age: int
gender: str = 'Unknown'
assert Person('me', '24').gender == 'Unknown'
其它的一句话更新包括:
async
/await
现在是保留关键字了.- 新增了
breakpoint()
系统函数用于调试. - 可以通过定义包的
__getattr__()
来控制包变量的访问行为. - 标准包
time
支持了纳秒级的精度. - 标准包
asyncio
更新了一大串功能,使其变得好用了.
What’s new in Python 3.8
Python 3.8 是在 2019-10-14 发布的,官方维护至 2024-10-14。
感知比较大的几个改动包括:
# 新增了赋值判断的语法(也被形象地叫做海象操作符)
import re
if match := re.search(r"(\d+)%", "Total coverage: 80%"):
print("Coverage is {match.group(1)}")
# 函数支持用 `/` 限制非命名参数
def calculate_data_length(data, /):
pass
# 官方指出,这种情况 `calculate_data_length(data=data)` 的可读性显然更低,其实可以在定义函数时禁掉
# 而且该语法可以避免 `**kwargs` 传参冲突的情况
def get_values(data, /, **kwargs):
print(data, kwargs)
get_values({}, data='some_data')
# f-strings 支持了自解释的语法
name = "ackerr"
assert f"Debug: {name=}" == "Debug: name='ackerr'"
# 新增了 `functools.cached_property` 方法,支持属性的缓存
import functools
class DB:
@functools.cached_property
def connection(self):
print(1)
db = DB()
assert db.connection == None
assert db.connection == None
其它的一句话更新包括:
finally
语句中不允许使用continue
了.- 新增了计算欧几里得距离的方法
math.dist()
. - 新增了支持混合l类型的
typing.TypedDict
. - 标准包
asyncio
更新了一大串功能,使其变得稳定了. - 官方给出的 benchmark 中,相比于 py37 总体性能提升了 5%~20%.
What’s new in Python 3.9
Python 3.9 是在 2020-10-05 发布的,官方维护至 2025-10-05。
感知比较大的几个改动包括:
# dict 支持并集操作符 `|` 了
x = {"a": 1, "b": 2}
y = {"b": 3, "c": 4}
assert x | y == {"a": 1, "b": 3, "c": 4}
assert y | x == {"a": 1, "b": 2, "c": 4}
# 支持 `list`/`dict`/`set` 这样的原生类型作为类型标注
def occurance(names: list[str]) -> dict[str, int]:
return {name: names.count(name) for name in names}
其它的一句话更新包括:
- 编译器由基于LL, 改为了基于PEG, 以便日后提供更强大的语言特性.
- 新增了
str.removeprefix()
/str.removesuffix()
方法. hashlib
支持了SHA3
/SHAKE
的计算.- 非 Windows 平台不支持构建
bdist_wininst
了(所以很多第三方库没及时更新). - 官方给出的 benchmark 中,相比于 py37 总体性能并无提升.
What’s new in Python 3.10
Python 3.10 是在 2021-10-04 发布的,官方维护至 2026-10-04。
感知比较大的几个改动包括:
# 新增了类似 switch+case 的 match+case 语法
def check(status_code: int, message: str):
match status_code:
case 200 if message:
return message
case 200:
return "ok"
case 400:
return "bad request"
case 500 | 502 | 503:
return "something wrong"
case _:
return "not implemented"
# `typing.Union` 可以写成更优雅的 `|`
def add_all(*numbers: int | float) -> int | float:
return sum(numbers)
assert isinstance(42, int | float)
# `dataclass` 支持 keyword-only 模式
import dataclasses as dc
@dc.dataclass(kw_only=True)
class Person:
name: str
age: int
gender: str = 'Unknown'
其它的一句话更新包括:
- 优化了 Python 自带的各种报错信息.
- 增加了
zip(*args, strict=True)
强制校验等长的参数. - 优化了
str()
/bytes()
的性能,日常情况中快了 40%.
结语
可以看到 Python 作为一个“步入成年的”编程语言,
这几年并没有 Golang 的泛型、错误处理那样令人 excited 的更新。
但总体的语言迭代也是基于 Python Zen 的小步快跑。
对于开发者而言,只要第三方依赖允许,
保持最新的环境并不是一个很难的事情。
笔者关心的功能只是语言标准的一个子集,
读者们也可以在官网上找到更详细、更实在的 changelog。
下期(如果还有的话)可能会带来 go115-go117 的版本变更日志,
到时候再见 :)
(完)