早在之前关于 Python 新版本的文档在官方一就直处于更新模式中,就在昨日 Python 3.8 稳定版正式发布了,让我们来看看新版本有哪些新特性呢?

Python 3.8.0 稳定版的新特性

PEP 572,赋值表达式

有一种新语法:=可将值赋给变量,作为较大表达式的一部分。由于它与海象的眼睛和象牙很像,因此被亲切地称为“海象操作员”。

在此示例中,赋值表达式有助于避免调用 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]

尝试限制使用海象运算符来清理可降低复杂性并提高可读性的案例。

PEP 570,仅位置的参数

有一个新的函数参数语法,/以指示某些函数参数必须在位置上指定,并且不能用作关键字参数。这 help() 与用 Larry Hastings 的 Argument Clinic 工具注释的 C 函数所显示的符号相同。

并行文件系统缓存,用于编译的字节码

新的 PYTHONPYCACHEPREFIX 设置(也可作为 )将隐式字节码缓存配置为使用单独的并行文件系统树,而不是每个源目录中的默认子目录。-X pycache_prefix__pycache__

缓存的位置报告在 sys.pycache_prefix (None指示__pycache__ 子目录中的默认位置)。

调试版本与发行版本共享 ABI

不管是在发布模式还是调试模式下构建,Python 现在都使用相同的 ABI。在 Unix 上,当 Python 以调试模式构建时,现在可以加载以发布模式构建的 C 扩展和使用稳定 ABI 构建的 C 扩展

f 字符串支持一个方便的 = 说明符进行调试

= 在 f-string 中添加了一个说明符。f 字符串(例如) f'{expr=}' 将扩展为表达式的文本,等号,然后扩展为求值表达式的表示形式

PEP 578:Python运行时审核挂钩

PEP 添加了“审核挂钩”和“已验证的打开挂钩”。两者都可以从 Python 和本机代码获得,从而允许使用纯Python代码编写的应用程序和框架利用额外的通知,同时还允许嵌入程序或系统管理员在始终启用审核的情况下部署Python 版本。

PEP 587:Python初始化配置

在 PEP 587 添加了新的 C API 以配置 Python 初始化,从而提供了对整个配置的更好控制和更好的错误报告。

该 PEP 还向这些内部结构添加了_PyRuntimeState.preconfig(PyPreConfig类型)和 PyInterpreterState.config(PyConfig类型)字段。PyInterpreterState.config 成为新的参考配置,替换全局配置变量和其他私有变量。

Vectorcall:对于 CPython 的一个快速调用协议

“ vectorcall”协议已添加到 Python / C API。它旨在将已经针对各种类进行的现有优化形式化。任何实现可调用的扩展类型都可以使用此协议。目前这是临时的,目的是使其在 Python 3.9 中完全公开。

pickle 协议 5 用于出带外数据缓冲器

当 pickle 用于在 Python 进程之间传输大数据以利用多核或多计算机处理时,重要的是通过减少内存副本并可能通过应用自定义技术(例如依赖数据的压缩)来优化传输。

该 pickle 协议5 引入用于出带外缓冲器,其中支持可以根据通信层的判断,与 PEP 3118 兼容的数据与主 pickle 流分开发送。

其他语言的变化

一个 continue 说法是非法 finally 条款因与实施问题。在Python 3.8中,这一限制被取消了。continue 现在在 finally: 块中。

该 int 类型现在具有 as_integer_ratio() 与现有 float.as_integer_ratio() 方法兼容的新方法.

增加了对 \N{name} 的支持。

Dict 和 dictviews 现在可以使用反向插入顺序进行迭代 reversed()。

函数调用中允许关键字名称的语法进一步受到限制。特别是, f((keyword)=arg) 不再允许。

现在允许 Iterable 解包,而不使用括号 yield 和 return 语句。

不是有效转义序列的反斜杠字符对 DeprecationWarning从Python 3.6 开始生成。在Python 3.8中它生成了一个SyntaxWarning代替。

SyntaxWarning 在某些情况下,编译器会在元组或列表之前错过逗号时生成

子类之间的算术运算 datetime.date 或 datetime.datetime 与datetime.timedelta 对象现在返回子类的实例,而不是基类。这也会影响其实现(直接或间接)使用 datetime.timedelta 算术的操作的返回类型。例如 datetime.datetime.astimezone()。

当 Python 解释器被 Ctrl-C(SIGINT)中断并且 KeyboardInterrupt 未捕获到的结果异常时,Python 进程现在通过 SIGINT 信号或正确的退出代码退出,以便调用进程可以检测到它因 Ctrl 而死亡-C。POSIX 和 Windows 上的shell使用它来正确终止交互式会话中的脚本。

.........

新模块

新 importlib.metadata 模块提供(临时)支持,用于从第三方程序包中读取元数据。例如,它可以提取已安装的软件包的版本号,入口点列表等:

>>> # Note following example requires that the popular "requests"
>>> # package has been installed.
>>>
>>> from importlib.metadata import version, requires, files
>>> version('requests')
'2.22.0'
>>> list(requires('requests'))
['chardet (<3.1.0,>=3.0.2)']
>>> list(files('requests'))[:5]
[PackagePath('requests-2.22.0.dist-info/INSTALLER'),
 PackagePath('requests-2.22.0.dist-info/LICENSE'),
 PackagePath('requests-2.22.0.dist-info/METADATA'),
 PackagePath('requests-2.22.0.dist-info/RECORD'),
 PackagePath('requests-2.22.0.dist-info/WHEEL')]

改进模块

异步

运行将启动本地异步 REPL。这样就可以快速测试具有顶级代码的代码。不再需要直接调用,这将在每次调用时产生一个新的事件循环:python -m asyncioawaitasyncio.run()

$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello

在 Windows 上,默认事件循环现在为 ProactorEventLoop

AST

AST 节点现在具有 end_lineno 和 end_col_offset 属性,可以提供节点末端的精确位置。(这仅适用于具有 lineno 和 col_offset 属性的节点。)

新函数 ast.get_source_segment() 返回特定 AST 节点的源代码。

该 ast.parse() 函数具有一些新标志:

type_comments=True 使它返回的文本 PEP 484 和 与某些 AST 节点相关联的 PEP 526 类型注释;

mode='func_type' 可以用来解析 PEP 484 “签名类型注释”(针对功能定义 AST 节点返回);

feature_version=(3, N)允许指定较早的 Python 3版本。(例如,将 和视为非保留字。)feature_version=(3, 4)asyncawait

集合

现在的 _asdict() 方法 collections.namedtuple() 返回 dict 而不是collections.OrderedDict。之所以可行,是因为自 3.7 以来,常规命令就保证了排序。如果需要的其他功能 OrderedDict,建议的补救措施是将结果转换为所需的类型:OrderedDict(nt._asdict())。

日期时间

添加了新的备用构造函数datetime.date.fromisocalendar()和 datetime.datetime.fromisocalendar(),分别从 ISO 年,周号和工作日构造date和 datetime 对象;这些是每个类的 isocalendar 方法的反函数。

GC

get_objects() 现在可以接收可选的生成参数,该参数指示从中获取对象的生成。

单元测试

添加 AsyncMock 以支持的异步版本 Mock。还添加了用于测试的适当的新断言函数。

已添加 addModuleCleanup() 和 addClassCleanup() 进行单元测试以支持对 setUpModule() 和的 清理 setUpClass()。

现在,一些模拟断言函数还会在失败时打印实际调用的列表。

unittest 该模块获得了对协程的支持,可以与协程一起使用unittest.IsolatedAsyncioTestCase。

例:

import unittest


class TestRequest(unittest.IsolatedAsyncioTestCase):

    async def asyncSetUp(self):
        self.connection = await AsyncConnection()

    async def test_get(self):
        response = await self.connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)

    async def asyncTearDown(self):
        await self.connection.close()


if __name__ == "__main__":
    unittest.main()

.........

其他

在 macOS 上,默认情况下现在在多处理中使用 spawn start 方法

现在,多处理(multiprocessing)可以使用共享内存段

typed_ast 合并回 CPython

LOAD_GLOBAL 现在快了 40%

pickle 现在默认使用协议 4,提高了性能

新增、改进具体信息太多,详细的我们就b不一一给大家罗列了,小伙伴们可边用边自行查看官方文档了解新改变(地址:https://docs.python.org/3.8/whatsnew/changelog.html#changelog)