[ 导读 ]Python 官网静悄悄地发布了一则大消息:正式发布 Python 3.8.0!新版本较3.7版增加了一大波新功能和优化,来一起参与讨论吧~
近日,Python 官网宣布,正式发布 Python 3.8.0!
代表 Python 开发社区和 Python 3.8 发布团队,我们很高兴地宣布 Python 3.8.0 现在已经可以使用。
Python 3.8.0 是 Python 语言的最新正式版,包含许多新功能和优化。
Python 的大多数第三方库也应该很快就会支持 3.8.0 软件包。
有关 3.8 版本功能的更多信息,请参阅 “Python 3.8 新特性” 文档。所有更改的详细信息都可以在更改日志中找到。
从 2019 年 12 月开始,3.8 系列的维护版本将定期每两个月发布一次。
感谢所有帮助 Python 开发和这些发布的志愿者!欢迎通过志愿或组织捐赠支持 Python 软件基金会的工作。
那么,这次新发布的 Python 3.8.0 有哪些重要的改进呢?以下是 Python 3.8 相比 3.7 的新增特性。
-
-
-
PEP 587,Python 初始化配置(改进的嵌入)
-
PEP 590,Vectorcall:用于 CPython 的快速调用协议
-
PEP 578, Python Runtime Audit Hooks
-
PEP 574,具有外部数据缓冲区的 pickle 协议 5
-
与打字相关:PEP 591(最终限定词),PEP 586(文学类型)和 PEP 589(TypedDict)
-
-
-
f - 字符串支持 = 用于自动记录表达式和调试文档
-
在 Windows 上,默认 asyncio 事件循环现在是 ProactorEventLoop
-
在 macOS 上,spawn 启动方法默认使用 multiprocessing
-
multiprocessing 现在可以使用共享内存段来避免进程之间的酸洗成本
-
-
-
接下来,我们重点来看几个(来自Python 3.8 文档)。
Python 3.8.0 有一个新的语法 :=,它将值赋给一个更大的表达式中的变量。它被亲切地称为 “海象运算符”(walrus operator),因为它长得像海象的眼睛和象牙。
这个 “海象运算符” 在某些时候可以让你的代码更整洁,比如:
在这个示例中,赋值表达式可以避免调用 len () 两次:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
类似的益处还可出现在正则表达式匹配中需要使用两次匹配对象的情况中,一次检测用于匹配是否发生,另一次用于提取子分组:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0
此运算符也适用于配合 while 循环计算一个值来检测循环是否终止,而同一个值又在循环体中再次被使用的情况:
# Loop over fixed length blocks
while (block := f.read(256)) != '':
process(block)
另一个值得介绍的用例出现于列表推导式中,在筛选条件中计算一个值,而同一个值又在表达式中需要被使用:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
请尽量将海象运算符的使用限制在清晰的场合中,以降低复杂性并提升可读性。
了解详情:
https://www.python.org/dev/peps/pep-0572
(由 Morehouse 在 bpo-35224 中贡献。)
新增了一个函数形参语法 / 用来指明某些函数形参必须使用仅限位置而非关键字参数的形式。这种标记语法与通过 help () 所显示的使用 Larry Hastings 的 Argument Clinic 工具标记的 C 函数相同。
在下面的例子中,形参 a 和 b 为仅限位置形参,c 或 d 可以是位置形参或关键字形参,而 e 或 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
f(10, 20, 30, d=40, e=50, f=60)
f(10, b=20, c=30, d=40, e=50, f=60)
f(10, 20, 30, 40, 50, f=60)
这种标记形式的一个用例是它允许纯 Python 函数完整模拟现有的用 C 代码编写的函数的行为。例如,内置的 pow () 函数不接受关键字参数:
def pow(x, y, z=None, /):
"Emulate the built in pow() function"
r = x ** y
return r if z is None else r%z
另一个用例是在不需要形参名称时排除关键字参数。例如,内置的 len () 函数的签名为 len (obj, /)。这可以排除如下这种笨拙的调用形式:
len(obj='hello') # The "obj" keyword argument impairs readability
另一个益处是将形参标记为仅限位置形参将允许在未来修改形参名而不会破坏客户的代码。例如,在 statistics 模块中,形参名 dist 在未来可能被修改。这使得以下函数描述成为可能:
def quantiles(dist, /, *, n=4, method='exclusive')
...
由于在 / 左侧的形参不会被公开为可用关键字,其他形参名仍可在 **kwargs 中使用:
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)...
>>> f(10, 20, a=1, b=2, c=3)
10 20 {'a': 1, 'b': 2, 'c': 3}
这极大地简化了需要接受任意关键字参数的函数和方法的实现。例如,下面是 collections 模块中的代码摘录:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
https://www.python.org/dev/peps/pep-0570
(由 Pablo Galindo 在 bpo-36540 中贡献。)
新增的 PYTHONPYCACHEPREFIX 设置 (也可使用 -X pycache_prefix) 可将隐式的字节码缓存配置为使用单独的并行文件系统树,而不是默认的每个源代码目录下的 __pycache__ 子目录。
缓存的位置会在 sys.pycache_prefix 中报告 (None 表示默认位置即 __pycache__ 子目录)。
(由 Carl Meyer 在 bpo-33499 中贡献。)
发布构建和调试构建现在都是 ABI 兼容的:定义 Py_DEBUG 宏不会再启用 Py_TRACE_REFS宏,它引入了唯一的 ABI 不兼容性。Py_TRACE_REFS 宏添加了 sys.getobjects () 函数和 PYTHONDUMPREFS 环境变量,它可以使用新的 ./configure --with-trace-refs 构建选项来设置。
(由 Victor Stinner 在 bpo-36465 中贡献。
)
f - 字符串支持 = 用于自动记录表达式和调试文档
增加 = 说明符用于 f-string。形式为 f'{expr=}' 的 f - 字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值结果。例如:
>>> user = 'eric_idle'
>>> member_since = date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
通常的 f - 字符串格式说明符 允许更细致地控制所要显示的表达式结果:
>>> delta = date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
= 说明符将输出整个表达式,以便详细演示计算过程:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
(由 Eric V. Smith 和 Larry Hastings 在 bpo-36817 中贡献。)
PEP 587: Python 初始化配置
PEP 587 增加了一个新的 C API 用来配置 Python 初始化,提供对整个配置过程的更细致控制以及更好的错误报告。
Vectorcall: 用于 CPython 的快速调用协议
添加 "vectorcall" 协议到 Python/C API。它的目标是对已被应用于许多类的现有优化进行正式化。任何实现可调用对象的扩展类型均可使用此协议。
此特性目前为暂定状态,计划在 Python 3.9 将其完全公开。
https://www.python.org/dev/peps/pep-0590
(由 Jeroen Demeyer 和 Mark Shannon 在 bpo-36974 中贡献。)
当使用 pickle 在 Python 进程间传输大量数据以充分发挥多核或多机处理的优势时,非常重要一点是通过减少内存拷贝来优化传输效率,并可能应用一些定制技巧例如针对特定数据的压缩。
pickle 协议 5 引入了对于外部缓冲区的支持,这样 PEP 3118 兼容的数据可以与主 pickle 流分开进行传输,这是由通信层来确定的。
https://www.python.org/dev/peps/pep-0574
(由 Antoine Pitrou 在 bpo-36785 中贡献。)
更多详细特性,请查阅Python 3.8.0文档:
https://docs.python.org/zh-cn/3.8/whatsnew/3.8.html
在2019年度 IEEE Spectrum 编程语言排行榜中,Python 不负众望,稳居榜首,而且连续三年夺冠。
IEEE Spectrum 2019 十大编程语言排行如上
Python 的流行在很大程度上是受了大量可用专用库的驱动,特别是在人工智能领域中。事实上,Keras 库对深度学习开发人员影响很大。但深度学习并不是 Python 产生巨大影响的唯一领域,微处理器计算能力的显著提高意味着嵌入式版本的 Python:如 CircuitPython 和 MicroPython,正越来越受制造商的欢迎。
Python 的高速发展主要原因是软件工程的蓬勃发展,它吸引了许多零基础的初学者。Java 的编程方法对于初学者来说太冗长了,单单想要完全理解和运行在 Java 中的 “hello world” 这样的简单程序,你就需要去了解类、静态方法和包。在 C 语言中,这要简单一些,但是在内存管理上还是会出现一些问题。但在 Python 这里,就只是一行代码的事。所以,Python 越来越流行,被越来越多的开发者使用。
对初学者友好,是 Python 用户快速增加的原因之一。如果你还不了解Python,那么最近微软推出的一套免费入门教程是很好的选择。
https://www.youtube.com/playlist?list=PLlrxD0HtieHhS8VzuMCfQD4uJ9yne1mE6
这套视频教程名为 Python for Beginners,由微软高级项目经理 Christopher Harrison、以及微软 AI Gaming 的商业开发经理 Susan Ibach 共同讲解,在课程中加入了他们对 Python 的见解,一共有 44 个视频。
这套课程最大的特定是轻松简洁,一上线就很受欢迎,5 天视频播放量超 25 万,更一度登上 GitHub 趋势榜第一名。
很简单,如果你想尝试前面介绍的 Python 3.8 的任何新功能,那么就应该升级到 Python 3.8。像 Pyenv 和 Anaconda 这样的工具可以很容易地并排安装多个版本的 Python。或者,你也可以运行官方的 Python 3.8 Docker 容器。尝试使用一下 Python 3.8,肯定会眼前一亮~
不过,是否应该将生产环境升级到 Python 3.8 呢?这需要考虑你的项目是否依赖 Python 3.8 的新功能。升级环境以运行 Python 3.8 是非常安全的,而且也能利用新版本中的优化。不过,如果你想保守一点,可以坚持到第一个维护版本(Python 3.8.1)发布时再升级。
如何评价 Python 3.8?欢迎来评论
一起讨论~
https://docs.python.org/zh-cn/3.8/whatsnew/3.8.html
编辑:黄继彦
校对:洪舒越