来源
https://docs.python.org/3/whatsnew/3.6.html
变更
- array.array 即使迭代的数组被扩展,耗尽的迭代器现在仍然会耗尽。与其他可变序列的行为保持一致。
- 从Python 3.6开始,asyncio模块被认为是稳定的。
- hashlib 支持 OpenSSL 1.1.0。
- 导入无法找到模块时引发新的异常ModuleNotFoundError (子类ImportError)。
- json.load()和json.loads()支持二进制输入。编码的JSON应使用UTF-8,UTF-16或UTF-32表示。
- dict类型改由PyPy实现,dict()与Python 3.5相比,新内存的使用量减少了20%到25%。
- 新功能 WatchedFileHandler.reopenIfNeeded() 用于检查是否需要重新打开日志文件。
- scandir()迭代器支持上下文管理协议
- scandir()支持Windows上的bytes路径。
- random.choices() 返回给定总体中具有可选权重的指定大小的元素列表
- 标准库添加新模块 secrets,
提供可靠的方法,用来随机生成加密加强的随机值,用于帐户认证,令牌等。
PEP 498:格式化字符串文字
PEP 498引入了一种新的格式化字符串的形式,将要
格式化的字符串文字添加前缀’f’,格式化的字符串中将要被替换的内容用{}包围,替换字段是表达式,使用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 526:变量注释的语法
PEP 484引入了函数参数类型注释标准,即类型提示。添加了类变量和实例变量的注释语法标准:
primes: List[int] = []
captain: str # Note: no initial value!
class Starship:
stats: Dict[str, int] = {}
与函数注释一样,Python解释器不会将任何特定含义附加到变量注释,只将它们存储在__annotations__属性中。
与静态类型语言中的变量声明相比,注释语法的目标是为第三方工具和拥有__annotations__属性的语法库提供方便的结构化初始数据的方法。
PEP 515:数字文字中的下划线
PEP 515增加了在数字文字中可以使用下划线,以提高可读性
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
PEP 525:异步生成器
PEP 492引入了 Python 3.5支持了async/await语法,但是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 530:异步的一些使用
PEP 530增加了 使用 async for 生成 列表/元祖/字典推导式
import asyncio
async def aiter(num=10):
for i in range(num):
await asyncio.sleep(0.01)
yield i
async def hello():
return [i async for i in aiter() if i % 2]
相当于:
async def hello():
result = []
async for i in aiter():
if i % 2:
result.append(i)
return result
await 表达式 可以在任何推导式中使用
result = [await fun() for fun in funcs if await condition()]
cmatch
- cmath.tau (τ) 添加到 cmath 模块中。
- 添加了新的常量: cmath.inf and cmath.nan,这两个分别匹配math.inf and math.nan
PEP 487:更简单的创建自定义类
可以在不使用元类的情况下自定义子类创建。每当创建新的子类时,都会在基类上调用__init_subclass__。允许零参数super()调用使__init_subclass__()正常执行,自定义的元类必须确保__classcell__ 命名空间条目传播到 type.new
class PluginBase:
subclasses = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
class Plugin1(PluginBase):
pass
class Plugin2(PluginBase):
pass
原来的自定义类写法:
class PluginBase:
subclasses = []
def __init_subclass__(cls, default_name, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
class Plugin1(PluginBase, default_name='AB'):
pass
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 519 添加文件系统路径协议
- os.PathLike 通过实现 fspath()方法来表示文件系统路径。
– 文件系统路径可以由 str、bytes对象或一个实现了os.PathLike方法的对象表示。 - 内置open()函数可以接受 os.PathLike对象
>>> 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'
PEP 495 当地时间纠正
有的地方,会将本地实际进行纠正,这种情况,可能会引起同一天出现两个相同的时间
PEP 495 添加了 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
PEP 529:将Windows系统的文件编码更改为UTF-8
str (Unicode) 在表示文件路径时优于 bytes。但是在某些情况下,bytes 可能会更好。
在Python 3.6之前,在Windows上使用 bytes 表示路径时可能会导致数据丢失。现在已经支持在Windows上使用 bytes 表示文件路径。
将Windows控制台编码更改为UTF-8
- Windows上的默认控制台现在接受所有Unicode字符,并为Python代码提供正确的str对象。
- sys.stdin, sys.stdout并且sys.stderr现在默认为UTF-8编码。
此更改仅适用于使用交互式控制台。要恢复到以前的交互式控制台使用行为,需要设置PYTHONLEGACYWINDOWSSTDIO。
PEP 468:保留关键字参数顺序
**kwargs 的参数保留传入顺序。
Decimal.as_integer_ratio() 返回一对整数
>>> Decimal('-3.14').as_integer_ratio()
(-157, 50)
enum模块
- 添加了两个新的枚举基类: Flag和IntFlags。两者都用于定义可以使用按位运算符组合的常量。
- enum.auto值可用于自动为枚举成员分配值:
>>> from enum import Enum, auto
>>> class Color(Enum):
... red = auto()
... blue = auto()
... green = auto()
...
>>> list(Color)
[<Color.red: 1>, <Color.blue: 2>, <Color.green: 3>]