过去几年,在编程语言领域 Python 可谓大红大紫。开发者对于这门语言的热情也推动了Python 语言的的快速发展。自2015年开始,Python 几乎以每年一个主要版本的速度不断的演进。
就在三个月前,我们注意到在Python 官网上悄然发布了最新的稳定版本Python 3.8。如果只是从数目字来看似乎只有0.1的变化,但如果仔细的阅读PEP文档,还是要不禁为Python 3.8 叫一声好!
Python 3.8 的新特性
说起来这次发布的新版本从2019年夏天就开始就有了测试版本,短短的几个月后在 2019年10月14日第一个官方的稳定版本就已经准备好了。这足以看出Python 社区对这个新版本的热情。而这个稳定的版本的出现,可以让我们即刻就开始使用 Python 的新特性并从最新的改进中获益。
与目前使用最为广泛的Python 3.7对比起来,Python3.8 的变化主要表现在这几个方面 –PEP 572,赋值表达式
PEP 570,仅限位置的形参
PEP 587,Python 初始化配置(改进的嵌入)
PEP 590,Vectorcall:用于 CPython 的快速调用协议
PEP 578, Python 运行时审计挂钩
PEP 574,具有外部数据缓冲区的 pickle 协议 5
与打字相关:PEP 591(最终限定词)、PEP 586(文字类型)和 PEP 589(TypedDict)
并行文件系统缓存,用于编译的字节码
调试版本使用与发布版本使用相同的 ABI
f – 字符串支持的便捷性 = 用于调试的说明符
在finally:块中,continue现在是合法的
在 Windows 上,默认 asyncio 事件循环现在是 ProactorEventLoop
在 macOS 上,spawn 启动方法默认使用 multiprocessing
multiprocessing 现在可以使用共享内存段来避免进程之间的pickle开销
typed_ast 被合并回了 CPython
LOAD_GLOBAL 速度加快了 40%
pickle 现在默认使用协议 4,提高了性能
在这些变化当中,给我留下深刻印象的有这样几个特性 –赋值表达式
Python 3.8 这一次增加了一个新的语法 :=,用来将值赋给一个表达式中的变量。这个新方法也被亲切地称为 “海象运算符” (walrus operator),因为这个表达式看起来像是海象的眼睛和象牙。具体用法是这样的
以前,赋值只能以语句形式提供。对于Python 3.8,它可以在列表生成(list comprehensions)和其他表达式上下文中使用。仅限位置的形参
仅位置参数通过引入新的函数参数语法 “/“ 来指示某些函数参数必须在位置上指定且不能用作关键字参数,从而为库的开发者提供了更多控制权。
在描述API时,可以使用它们更好地表达预期的用法,并允许API以安全,向后兼容的方式发展。 它们还使Python语言与现有文档以及各种“内置”和标准库函数的行为更加一致。
代码调试中支持的 f-string
f-string(或者称为「格式化字符串」)是在 Python 3.6 版本中加入的特性。虽然这一特性非常方便,但是开发者发现 f-string 对调试没有实际的帮助。因此,Eric V. Smith 为 f-string 添加了一些语法结构,使其能够用于调试。于是, Python 3.8增加了在f-string内部使用赋值表达式的能力,需要注意的是f-string是从左到右计算的。
System V风格共享内存带来的性能的提升
在版本3.8中,Python开始支持System V风格的共享内存。这种支持允许创建可以在Python进程之间共享的内存段,因此有助于在进程之间共享数据时避免(反)序列化的成本。这个变化引入了一个新的管理器multiprocessing.managers.SharedMemoryManager。
该管理器允许基于管理器来访问此共享内存功能。 此外,还引入了一个名为multiprocessing.shared_memory 的新程序包。 这个程序包包含SharedMemory和ShareableList类。
前一个类提供对共享内存的“原始”访问,而后一个类则通过将其抽象为Python中的列表来提供对共享内存的访问。可以设想,这个特性对于进程间通讯的效率的提升将是显而易见的。
如果有兴趣,可以体验一下这段代码带来的两种场景的对比
安装 Python 3.8
Python 3.8 已经是一个稳定的版本,并且许多使用广泛的Python 包已经兼容于这个最新的版本。在我初步测试中,无论AWS 的Python 开发包boto3,还是NumPy,Django等等都可以很好的运行于Python 3.8 之上。如果需要自行体验这个最新版本,首先需要的就是在系统中安装Python 3.8。Ubuntu 18.04
在Ubuntu 18.04 官方的“仓库”中已经提供了Python 3.8 的程序包。我们只需要用这样一个简单的命令就可以完成安装 –sudo apt install -y python3.8
如果考虑到开发中的需要,还可以安装这几个包 –sudo apt install -y python3.8-dev python3.8-venv python3.8-doc
安装后的Python 版本是这样的 –
Amazon Linux 2
目前Amazon Linux 2 的官方”仓库” 以及EEPL的“仓库”中都没有提供Python 3.8 的安装包。不得已,我们只能自己动手。不过不用担心,我为大家准备了一个一键安装。安装脚本的内容是这样的 –
这个脚本看起来啰嗦,其实完成下载、编译、安装的过程却很快。在我的一台m5a.2xlarge 的实例上,仅仅用了大约28秒的时间就完成了全部过程。安装完成以后,我们就得到了完整的Python3.8 环境,可以让我们尽情体验这些新的特性了。
Python 3.8 的另一种玩法 – Amazon Lambda
上面提到的关于Python 3.8 的一切,其实与以往众多的Python新版本别无两样。但是斗转星移,我们今天使用Python 来开发已经远远不止这样的方式。这些新的方法你也许听说过,其中就有大热的AWS Lambda。可以说AWS Lambda 的横空出世,给了应用开发、部署以及管理带来全新的内容。 对于我们今天的话题Python 3.8 来说,AWS Lambda 也给出一种新的选择。
就在Python3.8 发布之后的第35天,Amazon 发布了AWS Lambda 对于Python 3.8的支持。我们可以将Python函数部署到AWS Lambda 上,利用Python 3.8 运行时来执行我们的Python 代码。
在考虑程序的兼容性的前提下,我们可以在众多Python 运行时的环境中进行选择。在程序的稳定性、性能、新特性等之间作出最适当的选择。目前在AWS Lambda 上提供的Python 运行时有这样几个版本 –
我应该升级到 Python 3.8 吗?
很简单,如果你打算尝试上文介绍的 Python 3.8 的任何新功能,那么就应该升级到 Python 3.8。像 Pyenv 和 Anaconda 这样的工具也可以很容易地安装多个版本的 Python,也包括了Python3.8。或者,你也可以运行官方的 Python 3.8 Docker 容器。这可能是另一个最简便的体验的方式
不过,是否应该将生产环境升级到 Python 3.8 呢?这需要考虑你的项目是否依赖 Python 3.8 的新功能以及程序的兼容性的问题。例如Nvidia 的TensorRT 的Python程序包目前还无法支持Python 3.8 。
至于AWS Lambda,我建议我们首先进行的是兼容性的测试,之后考虑一个周密的升级的计划。当然升级版本以运行 Python 3.8 可以说是非常安全的,而且我们的代码也能利用新版本的特性来进行优化。
考虑到历史上Python2 到Python3 的升级带来的巨大代价,我们还是尽早的开始考虑Python版本的渐进升级的策略吧。