Python3.6新特性官方文档中文版

翻译团队:Py字幕组
首发刊物:PyCN技术评论
Github:https://github.com/PyCN/PTR

由阿橙(@sinoandywong)召集,Ele(@ictar)、苍冥(@eastrd)组织翻译。


特别感谢:
Ele(@ictar):她为本文档的翻译做了大量工作,一个热爱美食的菇凉。
Py字幕组:一个各路大(dou)神(bi)聚集的团队。

感谢他们所作出的工作,圣诞快乐!
2016.12.25

版本: 3.6.0
日期: December 15, 2016
编辑: Elvis Pranskevichus<elvis@magic.io>,Yury Selivanov<yury@magic.io>
这篇文章介绍了与3.5相比, Python 3.6中多出的新特性。

摘要 - 发布亮点

新的语法特性:

PEP 498, 格式化字符串字面量
PEP 515, 数字字面量中的下划线
PEP 526, 变量注解中的语法
PEP 525, 异步生成器

PEP 520: 异步解析式


新的库模块:

secrets: PEP 506 - 在标准库中添加了Secrets模块


CPython实现的改进:

       重新实现了字典(dict)类型,以便能像PyPy的字典类型一样使用更紧凑的表达方式。与Python 3.5相比,这使字典的内存用量减少了20%到25%。
       用新协定优化了类的自定义建立。
类属性定义顺序(class attribute definition order)现在被保留了
       **kwargs内的元素顺序现在对应于将关键字(保留字)参数传递给函数的顺序
       新增了对DTrace和SystemTap probing的支持。

       新PYTHONMALLOC环境变量现在可用于调试解释器内存分配与访问错误。


标准库的重大改进:

       为asyncio模块开发了新功能、显著的可用性、性能优化,以及大量的错误修复。 从Python 3.6开始,asyncio模块不再是临时的了,其API也进入了稳定状态。
       实现了用于支持类路径对象(path-like objects)的新文件系统路径协议。 所有在路径(path)上使用的标准库函数都已更新,以便适应于新协议。
       datetime模块已获得对本地时间消歧(Local Time Disambiguation)的支持。
       针对typing模块的一些改进,使其不再是临时模块。

       tracemalloc模块已重大改进,现用于为ResourceWarning提供更好的输出,并为内存分配错误提供更好的诊断。 


安全相关的改进:

       新secrets模块被用于简化那些适用于管理密文的密码学安全伪随机数生成器(cryptographically strong pseudo-random numbers)的生成过程,如认证、token等。
       在Linux上,现将os.urandom()改成了阻塞模式,直到系统的urandom的熵池(entropy pool)的初始化具有更高的安全性。 解释请参见PEP 524。
       hashlib和ssl模块现已支持OpenSSL 1.1.0。
       改进了ssl模块的默认设置和特性集。

       新增了hashlib模块对BLAKE2、SHA-3、SHAKE哈希算法以及scrypt()密钥导出函数的支持。


Windows上的改进:

       PEP 528与PEP 529,Windows文件系统和控制台的编码已更改为UTF-8。
       当用户没有指定版本(通过命令行参数或配置文件)时,py.exe启动器以交互方式使用时,不再以Python 2优先于Python 3。 处理shebang行的方式保持不变 - 此处的“python”依旧指Python 2。
       python.exe和pythonw.exe已标记为长路径敏感(long-path aware),这意味着260字符路径限制可能不再适用。 有关详细信息,请参阅删除MAX_PATH限制。
       可以添加._pth文件以强制隔离模式(isolated mode)并完全指定所有搜索路径,以避免注册表查找和环境查找。 有关详细信息,请参阅文档。

       一个python36.zip文件现可用作一个地标(landmark)以臆指PYTHONHOME。 有关详细信息,请参阅文档。


新特性:

PEP 498: 格式化字符串

PEP 498引入了一种新的字符串:_f-strings_, 或者格式化字符串。


格式化字符串带'f'前缀,类似于str.format()接受的格式字符串。它们包含了由花括号括起来的替换字段。替换字段是表达式,它们会在运行时计算,然后使用format()协议进行格式化:


>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'


PEP 498 - 字符串插值。

      PEP由Eric V. Smith编写和实现。

PEP 526: 变量注释语法

PEP 484引入了函数参数的类型注释的标准,又名类型提示。这个PEP添加了用来注释变量(包括类变量和实例变量)类型的语法:



primes: List[int] = []

captain: str # Note: no initial value!

class Starship:
stats: Dict[str, int] = {}


        正如函数注释,Python解释器不附加任何特殊意义到变量注释上,只是将它们存储在一个类或者模块的__annotations__属性中。

       与静态类型语言中的变量声明相比,注释语法的目的在于提供一种简单的方式,通过抽象语法树和__annotations__属性,来为第三方工具和库指定结构化类型元数据。


PEP 526 - 变量注释语法。

       PEP由Ryan Gonzalez, Philip House, Ivan Levkivskyi, Lisa Roach, 和Guido van Rossum编写。由Ivan Levkivskyi实现。
       使用或将要使用这个新语法的工具:mypy, pytype, PyCharm等等。

PEP 515: 数值文字中的下划线

PEP 515添加了在数值文字中使用下划线的能力,以提高可读性。例如:


>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295


数字之间和任何基本符号之后允许单个下划线。不允许前置、后置或者多个连续的下划线。

字符串格式化语言现在还支持'_'选项,该选项用来通知对浮点表示类型和整型表示类型'd',会把下划线当成千位分隔符使用。对于整型表示类型'b', 'o', 'x', 和'X', 下划线将会被插入到每4个数字之间:


>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'



PEP 515 - 数值文字中的下划线


       PEP由Georg Brandl和Serhiy Storchaka编写。


PEP 525: 异步生成器

PEP 492 引入支持原生协程和async /await的语法到Python 3.5。

       在Python 3.5实现里的一个值得注意的

       局限性就在于它不可能使用await和`yield'在同一个函数体中。 而在Python 3.6中,这个限制
已解除,这使得定义异步生成器成为可能:


async def ticker(delay, to):
"""Yield numbers from 0 to *to* every *delay* seconds."""
for i in range(to):
yield i
await asyncio.sleep(delay)


新的语法允许更快更简洁的代码。

PEP 525 - 异步生成器

由Yury Selivanov撰写并实现的PEP。
PEP 530: 异步解析式

PEP 530 添加了对async for在list、set、dict解析式以及generator表达式中的使用支持:


result = [i async for i in aiter() if i % 2]

此外,所有解析式都支持“await”表达式:


result = [await fun() for fun in funcs if await condition()]
 
PEP 530 - 异步解析式

PEP 487: 用于建立类的更简单的自定义


现在可以在不使用元类的情况下自定义子类。每当创建一个新的子类时,新的__init_subclass__类方法将在基类上被调用,:

class PluginBase:
subclasses = []

def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)

class Plugin1(PluginBase):
pass

class Plugin2(PluginBase):
pass

为了允许零参数super()从_init_subclass __()实现中被正确的调用并工作,自定义元类必须确保新的__classcell__命名空间输入传递到type .__ new__(如创建类对象)


PEP 487 - 用于建立类的更简单的自定义

功能文档

PEP 487: 描述符协议增强

PEP 487 扩展描述符协议必须包括新的可选的__set_name __()方法。 每当定义一个新类时,新方法将会调用定义中所有的描述符,并给它们提供定义类的引用,以及类命名空间中给予描述符的名字。 换句话说,描述符的实例现在可以获知所有者类的属性名:


class IntField:
def __get__(self, instance, owner):
return instance.__dict__[self.name]

def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError(f'expecting integer in {self.name}')
instance.__dict__[self.name] = value

# this is the new initializer:
def __set_name__(self, owner, name):
self.name = name

class Model:
int_field = IntField()


PEP 487 - 用于建立类的更简单的自定义

PEP 519: 添加文件系统路径协议

       文件系统路径过去被表示为str或bytes对象。这会导致那些编写操作文件系统路径代码的人,假定这些对象只能是这两种类型之一(一个代表着文件描述符的int对象将不被计入即它不是一个文件路径)。
       不幸的是,这种假设局限了文件系统路径表示代方法,如已经存在的pathlib,同时也包括python的一些标准库。
       为了解决这种情况,定义了一个由os.PathLike表示的新接口。通过实现__fspath__()方法,一个对象表示一个路径,然后,可以将文件系统路径表示为一个较低等级的str或者bytes对象。这意味着,如果一个对象实现os.PathLike或者是str或bytes,该对象被认为是path-like,它代表一个文件系统路径。你可以使用os.fspath(),os.fsdecode()或os.fsencode()显式获取str以及/或bytes来表示一个path-like对象。
       内建函数open()已经更新,可以接受os.PathLike对象,以及在os和os.path模块中的所有函数,以及标准库中的大多数其他函数和类。类os.DirEntry以及pathlib中相关的类也已经可以实现os.PathLike。
       希望对操作文件系统路径基本功能的更新能够让第三方代码在不改变任何代码,或者至少是非常少的代码(例如,在操作path-like对象之前,在代码的开头调用os.fspath())的情况下,能够隐含地支持所有path-like objects对象。
下面举一些例子说明新接口是如何让预先存在的代码简单透明地使用pathlib.Path:


>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
... contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'
(由Brett Cannon, Ethan Furman, Dusty Phillips, and Jelle Zijlstra实现)


PEP 519 - 添加文件系统路径协议

PEP 495: 本地时间消歧


       世界上大多数地方,都曾经出现也将出现多次的时间回调。在这种时候,引入时间间隔用以表示本地时钟在同一天中出现两次相同的时间的情况,在这些情况下,本地时钟显示的时间(或存在在python datetime中的实例)不足及时表示特定的时刻。
       为了区分本地时间相同的两个时刻,PEP 495 在类 datetime.datetime 和 `datetime.time` 的实例中增加了新的fold属性:


>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
... u = u0 + i*HOUR
... t = u.astimezone(Eastern)
... print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0


属性 fold 的值除了表示不明确情况下的第二(时间顺序)时刻之外,其他所有实例的值都为 0。

PEP 495 - 本地时间消歧

PEP 529: 更改windows下文件系统编码格式为UTF-8


       使用str (Unicode) 表示文件系统路径比bytes能获得更好的效果。尽管如此,在某些情况下bytes也足以胜任并且也是正确的。

       在3.6之前,使用bytes路径可能导致数据丢失。改进后, windows下现在支持使用bytes表示路径,这些bytes将以sys.getfilesy
       stemencoding()的方式编码,默认编码格式为'utf-8'。

       不使用str方式表示路径的应用程序应当使用os.fsencode()和os.fsdecode() 以确保他们的bytes被正确编码。要回复到之前的状态, 设置 PYTHONLEGACYWINDOWSFSENCODING 或者调用            sys._enablelegacywindowsfsencoding()。

PEP 528: 更改windows控制台编码为UTF-8

       windows下的默认控制台现在支持所有的Unicode字符并可以正确读取Python代码中的str对象。sys.stdin, sys.stdout
       以及 sys.stderr 现在的默认使用utf-8编码。

       这一变化仅适用于使用交互控制台之时,而非重定向文件或者管道。如果要使用之前的交互控制台, 需设置 PYTHONLEGACYWINDOWSIOENCODING。


PEP 528 - 修改windows控制台编码为UTF-8

PEP 520: 保存类属性定义顺序


       类的定义体中的属性有一个自然顺序:即源码中属性名出现的顺序。 这个顺序现在保存在新的类__dict__ 的属性中.

      同样, 有效的缺省类和执行空间 (从type.prepare()返回)是一个保存插入顺序的映射。



PEP 520 - 保存类属性定义顺序

PEP 468: 保存关键字参数顺序


       函数声明中的**kwargs 的顺序现在被保证是插入顺序的映射。


PEP 468 - 保存关键字参数顺序


新的 字典dict类型的实现


       字典dict类型现在使用 PyPy首创的 "紧凑" 表达方式。 新字典dict() 的内存占用比Python3.5中减少20%到25%。

       新的实现中保存顺序的功能被认为是不可过于依赖的(未来也许会改变,不过在将所有当前和未来的Python实现的语言规范转换为保证顺序的语法之前的几个版本中,新的dict有望被实现的; 这也能帮助保证对那些仍旧是随机迭代顺序的旧版本的向后兼容,比如Python 3.5)。

       (由INADA Naoki在issue 27350提供。 想法 最初由Raymond Hettinger提出.)

PEP 523:添加一个frame解析API到CPython

       虽然Python提供了自定义代码执行方式的广泛支持,但是还有一个它没这样做的地方是frame对象的解析。如果你想要通过某些方式在Python中拦截frame解析,那么除了直接对定义的函数操作函数指针之外,真的没有什么其他方式。

       PEP 523改变了这个处境,它提供了一个API,让frame解析在C层次上可插拔。这将允许诸如调试器或者JIT这样的工具在Python代码开始执行之前拦截frame解析。这使得python代码的可替换解析实现、跟踪frame解析等地使用成为可能。

      这个API并不是受限的C API的一部分,并且被标为私有,表示期望限制这个API的使用,并且只能应用在非常选定的低层次用例上。这个API的语义将在必要的时候随着Python改动。

没有更多推荐了,返回首页