Python 3.8.0 正式版发布,新特性初体验

北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性。

赋值表达式

PEP 572: Assignment Expressions

新增一种新语法形式::=,又称为“海象运算符”(为什么叫海象,看看这两个符号像不像颜表情),如果你用过 Go 语言,应该对这个语法非常熟悉。

具体作用我们直接用实例来展示,比如在使用正则匹配时,以往版本中我们会如下写:

import re

pattern = re.compile('a')
data = 'abc'
match = pattern.search(data)
if match is not None:
print(match.group(0))

而使用赋值表达式时,我们可以改写为:

if (match := pattern.search(data)) is not None:
print(match.group(0))

在 if 语句中同时完成了求值、赋值变量、变量判断三步操作,再次简化了代码。

下面是在列表表达式中的用法:

filtered_data = [y for x in data if (y := func(x)) is not None]

强制位置参数

PEP 570: Python Positional-Only parameters

新增一个函数形参标记:/,用来表示标记左侧的参数,都只接受位置参数,不能使用关键字参数形式。

>>> def pow(x, y, z=None, /):
... r = x ** y
... return r if z is None else r%z
...
>>> pow(5, 3)
125
>>> pow(x=5, y=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pow() takes no keyword arguments

这实际上是用纯 Python 代码来模拟现有 C 代码实现的内置函数中类似功能,比如内置函数 len('string') 传参是不能使用关键字参数的。

Runtime 审计钩子

PEP 578: Python Runtime Audit Hooks

这让我们可以对某些事件和 API 添加一些钩子,用于在运行时监听事件相关的参数。

比如这里监听 urllib 请求:

>>> import sys
>>> import urllib.request
>>> def audit_hook(event, args):
... if event in ['urllib.Request']:
... print(f'{event=} {args=}')
...
>>> sys.addaudithook(audit_hook)
>>> urllib.request.urlopen('https://httpbin.org/get?a=1')
event = 'urllib.Request' args =( 'https://httpbin.org/get?a=1' , None , {}, 'GET' )
<http.client.HTTPResponse object at 0x108f09b38>

官方内置了一些 API,具体可查看 PEP-578 规范文档,也可以自定义。

f-strings 支持等号

在 Python 3.6 版本中增加了 f-strings,可以使用 f 前缀更方便地格式化字符串,同时还能进行计算,比如:

>>> x = 10
>>> print(f'{x+1}')
11

在 3.8 中只需要增加一个 = 符号,即可拼接运算表达式与结果:

>>> x = 10
>>> print(f'{x+1=}')
'x+1=11'

这个特性官方指明了适用于 Debug。

Asyncio 异步交互模式

在之前版本的 Python 交互模式中(REPL),涉及到 Asyncio 异步函数,通常需要使用 asyncio.run(func()) 才能执行。

而在 3.8 版本中,当使用 python -m asyncio 进入交互模式,则不再需要 asyncio.run

>>> import asyncio
>>> async def test():
... await asyncio.sleep(1)
... return 'test'
...
>>> await test()
'test'

跨进程共享内存

在 Python 多进程中,不同进程之间的通信是常见的问题,通常的方式是使用 multiprocessing.Queue 或者 multiprocessing.Pipe,在 3.8 版本中加入了 multiprocessing.shared_memory,利用专用于共享 Python 基础对象的内存区域,为进程通信提供一个新的选择。

from multiprocessing import Process
from multiprocessing import shared_memory share_nums = shared_memory.ShareableList(range(5)) def work1(nums):
for i in range(5):
nums[i] += 10
print('work1 nums = %s'% nums) def work2(nums):
print('work2 nums = %s'% nums) if __name__ == '__main__':
p1 = Process(target=work1, args=(share_nums, ))
p1.start()
p1.join()
p2 = Process(target=work2, args=(share_nums, ))
p2.start() # 输出结果:
# work1 nums = [10, 11, 12, 13, 14]
# work2 nums = [10, 11, 12, 13, 14]

以上代码中 work1 与 work2 虽然运行在两个进程中,但都可以访问和修改同一个 ShareableList对象。

@cached_property

熟悉 Python Web 开发的同学,对 werkzeug.utils.cached_propertydjango.utils.functional.cached_property 这两个装饰器一定非常熟悉,它们是内置 @property 装饰器的加强版,被装饰的实例方法不仅变成了属性调用,还会自动缓存方法的返回值。

现在官方终于加入了自己的实现:

>>> import time
>>> from functools import cached_property
>>> class Example:
... @cached_property
... def result(self):
... time.sleep(1) # 模拟计算耗时
... print('work 1 sec...')
... return 10
...
>>> e = Example()
>>> e.result
work 1 sec...
10
>>> e.result # 第二次调用直接使用缓存,不会耗时
10

其他改进

  • PEP 587: Python 初始化配置
  • PEP 590: Vectorcall,用于 CPython 的快速调用协议
  • finally: 中现在允许使用 continue
  • typed_ast 被合并回 CPython
  • pickle 现在默认使用协议4,提高了性能
  • LOAD_GLOBAL 速度加快了 40%
  • unittest 加入了异步支持
  • 在 Windows 上,默认 asyncio 事件循环现在是 ProactorEventLoop
  • 在 macOS 上,multiprocessing 启动方法默认使用 spawn

更多具体变化,可查看 What’s New In Python 3.8

Python 3.8.0 正式版发布,新特性初体验 全面介绍的更多相关文章

  1. Python 3.8.0 正式版发布,新特性初体验

    北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性. 赋值表达式 PEP 572: Assignment Expressi ...

  2. Redis 3.0正式版发布,正式支持Redis集群

    Redis是一个开源.基于C语言.基于内存亦可持久化的高性能NoSQL数据库,同时,它还提供了多种语言的API.近日,Redis 3.0在经过6个RC版本后,其正式版终于发布了.Redis 3.0的最 ...

  3. Appium路线图及1.0正式版发布

    Appium更新的速度极快,从我试用时候的0.12到1.0(0.18版本后就是1.0),完全符合移动互联网的节奏. 更新可能会慢,可以多试几次 整理了testerhome上思寒发表的帖子,让我们来看下 ...

  4. .NET Core 3.0正式版发布

    是的,.NET Core 3.0正式版发布了,令人兴奋. WPF 其实,.NET Core 2.1开始已经是个很完善的版本,3.0又带来了什么呢?我站在我的使用角度来看,最最令人振奋的就是:能用WPF ...

  5. Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架

    开发四年只会写业务代码,分布式高并发都不会还做程序员?   Nest.js 6.0.0 正式版发布了.Nest 是构建高效.可扩展的 Node.js Web 应用程序的框架.它使用现代的 JavaSc ...

  6. RestServer 2.0 正式版发布

    RestServer 2.0 正式版发布 使用许可&版权说明 在保持本软件完整的情况下可以将本软件用于任何商业用途. 本软件可以自由传播,但是请保持软件相关文件和说明文档完整. 未经许可不得将 ...

  7. React Suite v3.0 正式版发布

    React Suite v3.0 正式版发布 相信很多人会好奇,React Suite 是什么? React Suite 是 HYPERS 前端团队和 UX 团队开源的一套基于 React 的 UI ...

  8. Xcode 7.0正式版发布了

    Xcode 7.0正式版发布了     下载地址:链接: http://pan.baidu.com/s/1FNkPS 密码: ee42     本文由大学霸整理,转载请注明出处,尊重IT人!

  9. RapidJSON 1.0 正式版发布,C++的JSON开发包

    分享 <关于我> 分享  [中文纪录片]互联网时代                 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...

随机推荐

  1. Jmeter(十三)阶梯式压测

    阶梯式压测,就是对系统的压力呈现阶梯性增加的过程,每个阶段压力值都要增加一个数量值,最终达到一个预期值.然后保持该压力值,持续运行一段时间. Jmeter中有个插件可以实现这个场景,这个插件就是:Co ...

  2. java什么时候进行垃圾回收,垃圾回收的执行流程

    java的垃圾回收分为 三个区域新生代 老年代 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间如果有 不进行垃圾回收 ,对象直接在伊甸园存储.如果伊甸园内存已满,会进行一次minor gc然后 ...

  3. Kafka 实践

    问题描述 配置 Kafka-client 2.x, Spring-Kafka 默认配置 Kafka 三个partition, 使用KafkaListener按group消费. 现象 某天突然发现两个p ...

  4. docker 管理应用程序数据和网络管理

    Volume和Bind Mount Docker提供三种不同方式将数据从宿主机挂载到容器中:volumes,bind mounts和tmpfs volumes:Docker管理宿主机文件系统的一部分( ...

  5. js获取后台传给前台的值

    1.后台传给前台的方法 String rulemodeid=req.getParameter("rulemodeid"); req.setAttribute("rulem ...

  6. vsftpd 配置用户及根目录及其参数详解

    vsftpd 常用功能参数配置及参数详解 Table of Contents 1. 配置超级服务 2. 配置匿名用户 3. 配置本地用户登录 4. 配置虚拟用户登录 5. 使用SSL登入 6. 日志文 ...

  7. mybatis之分页查询

    1)StudentDao.java /** * 持久层*/ public class StudentDao { /** * 增加学生 */ public void add(Student studen ...

  8. [PySpark] RDD programming on a large file

    重难点 一.parallelize 方法 一般来说,Spark会尝试根据集群的状况,来自动设定slices的数目.然而,你也可以通过传递给parallelize的第二个参数来进行手动设置. data_ ...

  9. 关于 /proc/sys/net/ipv4/下 文件的详细解释

    关于 /proc/sys/net/ipv4/下 文件的详细解释: 1) /proc/sys/net/ipv4/ip_forward  该文件表示是否打开IP转发.      0,禁止      1,转 ...

  10. uni-app 封装 http promise请求,仅提供 post,all,spread 方法

    简单封装一下 uni-app 的请求,因为项目中只用 post 请求,所以只封装了 post 和 all 方法. 更新,新增 spread 方法 2019-11-22 10:37:21 global. ...