到目前为止,Python 3.8提出了7个功能

Python 3.7已发布。 如果您想了解所有内容,请观看我的Pluralsight.com课程。

Python 3.7从新功能和优化中受益。 从目前为止我们对3.8的了解来看,这将是一个类似的故事。 这次,大多数新功能都针对C扩展和模块开发。

根据针对3.8提交的现有Python增强建议或“ PEP”,我们对可能包含的功能有了很好的了解。 我在这里为3.8组合了一个PEP-Explorer UI。

到目前为止,Python 3.8提出了7个功能

许多提交的PEP处于草稿状态 ,这意味着实施细节尚未最终确定 而且,PEP必须先获得大师级(BD-Master)或BDFL的批准,然后才能获得批准。

我们将在2019年初看到第一个Beta ,它将在2019年6月左右“冻结”。

口译员的启动时间将得到改善

到目前为止,Python 3.8提出了7个功能

Python的启动时间一直很慢,这在解释型语言中很常见。 即使对于预编译的脚本(即具有现有.pyc缓存的Python文件),如果要启动多个进程,启动Python解释器所花费的时间也会成为问题。

如下图所示(越低速度越快),Python 3的启动速度比2.7慢,而PyPy由于JIT初始化过程的原因甚至更慢。

已经进行了优化启动的尝试,但是没有什么“大刀阔斧”产生重大影响。 据传3.8是此类改进的目标版本, PEP 432解释了将启动过程分为多个阶段的明确策略 这个想法是,当从命令行或通过WSGI进程运行python时,它将运行相同的初始化序列,而不管您是否要运行单元测试,探索REPL,运行1函数或执行预编译脚本。

研究表明,由于Python导入路径的复杂性和典型安装中库的数量,大多数Python启动时间都由I / O决定。

PEP432本身并不会提高启动性能,但是通过另一个( 尚未编写,我只是猜测会做到 ),PEP提出了如何预编译脚本可以将其导入序列和状态缓存或配置的建议,将产生巨大的变化。

有多个口译员

通过与启动时间的联系, PEP 554提出了一个新的标准库模块,即interpreters ,它将公开现有的C-API,以便在单个进程中具有多个Python解释器。 与整个Python流程相比,这可以在更少的开销下隔离代码。

PEP 554还建议扩展现有的API,以允许在数据解释器之间更好地共享。

可能是这样的:

import interpreters
interp = interpreters.create()
print('before')
interp.run('print("during")')
print('after')

“无意识”操作员

任何C#,Perl,PHP或Swift开发人员都可能熟悉Null-Aware运算符,该运算符可用于多种用途。 我最喜欢的C#之一是可识别空值的三元运算符。 在此示例中,将水果的值分配给val的值,除非它为null,在这种情况下,将其分配给"watermelon"的值。

var fruit = val ?? "watermelon";

PEP505None建议了 3个Python等效项,这些等效于此C#示例,但具有Python风味。

if val is None:
fruit = "watermelon"
else:
fruit = val
# now becomes in PEP505..
fruit = val ?? "watermelon"

不了解属性访问

if val.fruit is not None:
fruit = val.fruit.name()
else:
# now becomes in PEP505
fruit = val.fruit?.name()

同样,对于无法确定是否设置的值进行切片或索引。

list_of_things = get_values()  # could be ``list`` or None
first = list_of_things?[0]

另一个观察类似行为的PEPPEP 532

生成器敏感的上下文变量

PEP 567(包含在Python 3.7中)引入了上下文变量,它们是上下文本地状态,类似于线程本地存储。 它们与类似线程的环境(例如asyncio任务)很好地配合使用。

三位一体的Nathaniel Smith的PEP 568建立在PEP567的基础上,但增加了生成器上下文的敏感性。 对于使用asyncio并希望使用生成器的人来说,这是个好消息。 我现在不大量使用asyncio,所以这个问题有点困扰我。

扩展用于C扩展方法的API

Python具有@staticmethod@classmethod ,类方法通常在纯Python中定义,但也可以用C编写

  • PyType_GetModule
  • PyType_DefiningTypeFromSlotFunc
  • PyType_GetModuleState
  • PyErr_PrepareImmutableException

作业表达

这是3.8中最具争议的提议,并且它的一种形式已经被批准。

PEP 572建议对Python语法进行更改,以启用“赋值表达式”。 了解此更改需要理解Python中的语句表达式之间的差异。

Python有多种类型的简单语句,每种语句都以换行符结尾(除非您使用分号,例如import pdb; pdb.set_trace()

  • 导入语句- import foo
  • 流和通过语句,例如。 break
  • 表达式语句,例如。 x = yx += y

Python还具有某些类型的语句中找到的表达式

  • if语句具有if TEST: SUITE语法,其中SUITE是嵌套在空白中的一组语句,而TEST是单个比较表达式或使用a and or not关键字的一系列a。
  • 对于语句, for EXPRESSION LIST in TESTS: SUITE具有for EXPRESSION LIST in TESTS: SUITE的语法for EXPRESSION LIST in TESTS: SUITE
  • 删除语句del EXPRESSSION
  • 使用with TEST as EXPRESSION: SUITE语句with TEST as EXPRESSION: SUITE
  • 列表和字典理解

您无法将语句放入表达式中,因为语句不返回任何内容。 因此, if x = y:不起作用

>>> x = 1
>>> y = 2
>>> if x=y:
File "<stdin>", line 1
if x=y:
^
SyntaxError: invalid syntax

PEP 572建议使用新的:=运算符和赋值表达式的新型语法来更改此设置。

以这个例子为例,您有一个产品列表,并且想要计算运输总额。 当前在Python中,如果您在列表理解中使用if语句,则无法进行声明以分配某物的值。

使用此新语法,您可以。 此示例中的重要部分是列表理解中新名称cost的创建,列表理解是to_usd函数调用的产物。

是否想使用这种新语法?

我用赋值表达式语法和无值合并运算符语法构建了一个分支: https : //github.com/tonybaloney/cpython/tree/python38_wonderland

到目前为止,Python 3.8提出了7个功能

对内置函数类的更改

“ PEP576建议将内置函数和方法的类扩展为更类似于Python函数。 具体来说,内置函数和方法将有权访问声明它们的模块,内置方法将有权访问它们所属的类。”

为什么需要这个? 好吧,如果您正在开发Python模块(例如Cython)并想用C语言开发函数,则有两种选择:

  • 使用内置的CPython函数,例如lenprint等。这是首选方法,但是它对您可以在模块中访问的数据有缺点(如果使用Python实现,则没有此功能),或者
  • 构建自己的len,print等版本。通常这是一个坏主意。

该提案对C API进行了2处更改:

  1. 添加了一个新函数PyBuiltinFunction_New(PyMethodDef *ml, PyObject *module)以创建内置函数。
  2. PyCFunction_NewEx()PyCFunction_New()被取消,并将返回PyBuiltinFunction如果能,否则builtin_function_or_method

PEP还提出了一个新的内置类builtin_function

一个相关的PEP 573希望扩展API,使用C编写的扩展方法可以访问它们,从而使他们能够查看模块状态,而不必调用昂贵的PyState_FindModule操作。 同样,该实现对Cython最为有用,里程可能会有所不同。

另一个相关的PEP,580 ,是关系到扩展类型的发展建立在实例builtin_function_or_methodmethod_descriptormethodfunction y

这些类都不是可子类化的。 因此,无法基于有关方法,内置函数等的假设进行任何优化。

573建议用新的“ C调用”协议代替对builtin_function_or_methodmethod_descriptor的检查。

使用此新协议意味着用户开发的扩展类型将获得与内置插件相同的优化好处,例如Python 3.7中添加的新的LOAD_METHOD操作码快20%。

Python运行时审核挂钩

PEP 578建议将钩子添加到CPython运行时中 ,这些钩子将使开发人员能够:

  • 安全软件
  • 调试软件
  • 分析软件,以及其他一些我想不到的示例

“挂钩”到核心运行时事件并执行扩展代码。 该API将被添加到sys模块中,并具有可以任意调用该挂钩以及配置自己的挂钩的功能。 一旦添加,挂钩将无法删除或更换。

# Add an auditing hook
sys.addaudithook(hook: Callable[[str, tuple]])

# Raise an event with all auditing hooks
sys.audit(str, *args)

示例和建议的事件包括exec,import,compile和object .__ setattr__。 PEP对基本的低级挂钩(例如代码对象的执行)提出了一些建议,但也对较高级别的挂钩(如打开网络套接字和调用URL)提出了一些建议。

在最后的发言中,我可以听到各地安全保障人员的不满。 我非常喜欢这个PEP,因为它可能会导致CPython一些出色的第三方插件锁定执行环境。 类似于SELinux对Linux内核所做的事情。

挂钩将实现对事件的响应,典型的响应将是记录事件,异常中止操作或通过操作系统退出调用立即终止进程。

这是我能想到的一些示例用法

  • 检测核心对象和功能的猴子补丁
  • 默认情况下,所有非root用户都禁用/登录网络套接字
  • 陷阱/代理打开远程URL连接
  • 检测导入操作以捕获运行时及其测试的导入树。

From: https://hackernoon.com/7-features-proposed-so-far-in-python-3-8-acb0d97c83c8