原文:What’s New In Python 3.6 翻译团队:Py字幕组 首发刊物:PyCN技术评论(点击菜单栏:社区-刊物进入) Github:https://github.com/PyCN/PTR
由阿橙(@sinoandywong)召集,Ele(@ictar)、苍冥(@eastrd)组织翻译。
译者: eastrd:苍冥 ictar :Ele linchart szthanatos alex-marmot heyuanree sinoandywong:阿橙 sxqs-yang:若木羊 zilongcc:水手 bubuyo:铲屎官 yifan1024 YoungZiyi fuckexception Lving LoveSn0w phdhorse41
特别感谢: 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 494 - Python 3.6 发布时间表
新的语法特性:
新的库模块
secrets
: PEP 506 - 在标准库中添加了Secrets模块CPython实现的改进:
标准库的重大改进:
安全相关的改进:
hashlib
和ssl
模块现已支持OpenSSL 1.1.0。ssl模块
的默认设置和特性集。hashlib模块
对BLAKE2、SHA-3、SHAKE哈希算法以及scrypt()
密钥导出函数的支持。Windows上的改进:
._pth
文件以强制隔离模式(isolated mode)并完全指定所有搜索路径,以避免注册表查找和环境查找。 有关详细信息,请参阅文档。PYTHONHOME
。 有关详细信息,请参阅文档。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 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添加了在数值文字中使用下划线的能力,以提高可读性。例如:
>>> 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 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 添加了对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 - 异步解析式
由Yury Selivanov撰写并实现的PEP。
现在可以在不使用元类的情况下自定义子类。每当创建一个新的子类时,新的__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 - 用于建立类的更简单的自定义
由Martin Teichmann撰写并实现的PEP。
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 - 用于建立类的更简单的自定义
由Yury Selivanov撰写并实现的PEP。
文件系统路径过去被表示为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 由Brett Cannon 和 Koos Zevenhoven撰写.
世界上大多数地方,都曾经出现也将出现多次的时间回调。在这种时候,引入时间间隔用以表示本地时钟在同一天中出现两次相同的时间的情况,在这些情况下,本地时钟显示的时间(或存在在python datetime中的实例)不足及时表示特定的时刻。
为了区分本地时间相同的两个时刻,PEP 495 在类 datetime.datetime
和 `datetime.time` 的实例中增加了新的fold属性:
>>> 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'
属性 fold
的值除了表示不明确情况下的第二(时间顺序)时刻之外,其他所有实例的值都为 0
。
又见
PEP 495 - 本地时间消歧
PEP 由 Alexander Belopolsky 和 Tim Peters撰写, 由Alexander Belopolsky实现.
使用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 529以获取更多信息并讨论可能需要变更的代码。
windows下的默认控制台现在支持所有的Unicode字符并可以正确读取Python代码中的str对象。sys.stdin
, sys.stdout
以及 sys.stderr
现在的默认使用utf-8编码。
这一变化仅适用于使用交互控制台之时,而非重定向文件或者管道。如果要使用之前的交互控制台, 需设置 PYTHONLEGACYWINDOWSIOENCODING
。
另请参阅
PEP 528 - 修改windows控制台编码为UTF-8
PEP 由Steve Dower编写和实现。
类的定义体中的属性有一个自然顺序:即源码中属性名出现的顺序。 这个顺序现在保存在新的类__dict__
的属性中.
同样, 有效的缺省类和执行空间 (从type.prepare()返回)是一个保存插入顺序的映射。
另请参阅
PEP 520 - 保存类属性定义顺序
该PEP由Eric Snow编写和实现。
函数声明中的**kwargs
的顺序现在被保证是插入顺序的映射。
另请参阅
PEP 468 - 保存关键字参数顺序
该PEP由Eric Snow编写和实现。
字典dict类型现在使用 PyPy首创的 "紧凑" 表达方式。 新字典dict()
的内存占用比Python3.5中减少20%到25%。
新的实现中保存顺序的功能被认为是不可过于依赖的(未来也许会改变,不过在将所有当前和未来的Python实现的语言规范转换为保证顺序的语法之前的几个版本中,新的dict有望被实现的; 这也能帮助保证对那些仍旧是随机迭代顺序的旧版本的向后兼容,比如Python 3.5)。
(由INADA Naoki在issue 27350提供。 想法 最初由Raymond Hettinger提出.)
虽然Python提供了自定义代码执行方式的广泛支持,但是还有一个它没这样做的地方是frame对象的解析。如果你想要通过某些方式在Python中拦截frame解析,那么除了直接对定义的函数操作函数指针之外,真的没有什么其他方式。
PEP 523改变了这个处境,它提供了一个API,让frame解析在C层次上可插拔。这将允许诸如调试器或者JIT这样的工具在Python代码开始执行之前拦截frame解析。这使得python代码的可替换解析实现、跟踪frame解析等地使用成为可能。
这个API并不是受限的C API的一部分,并且被标为私有,表示期望限制这个API的使用,并且只能应用在非常选定的低层次用例上。这个API的语义将在必要的时候随着Python改动。
又见
PEP 523 - 添加一个frame解析API到CPython
PEP由Brett Cannon和Dino Viehland编写
(C) Copyright2001-2016,Python软件基金会版权所有。Python软件基金会是一个非营利性组织。