发布时间:2016 年 12 月 23 日
官方文档:https://docs.python.org/zh-cn/3.6/whatsnew/3.6.html
最受欢迎的新特性之一,比 % 和 .format() 更简洁高效:
name = "Fred"
f"He said his name is {name}." # 'He said his name is Fred.'
# 支持表达式和格式说明符
value = decimal.Decimal("12.34567")
f"result: {value:10.4f}" # 'result: 12.3457'
# 嵌套字段
width = 10
precision = 4
f"result: {value:{width}.{precision}}" # 'result: 12.35'
# 调用方法
f"{name.upper()}" # 'FRED'
提升大数字可读性:
1_000_000_000 # 1000000000
0x_FF_FF_FF_FF # 4294967295
1_000.000_001 # 1000.000001
# 格式化中的下划线分隔符
f'{1000000:,}' # '1,000,000'
f'{0xFFFFFFFF:_x}' # 'ffff_ffff'
支持对变量进行类型注解(不仅限于函数参数):
from typing import List, Dict
x: int = 10
primes: List[int] = []
captain: str # 无初始值!
class Starship:
stats: Dict[str, int] = {}
name: str = "Enterprise"
# 3.5:不能在同一个函数里同时使用 await 和 yield
# 3.6:解除限制,支持异步生成器
async def ticker(delay, to):
for i in range(to):
yield i
await asyncio.sleep(delay)
async for i in async_range(1, 5):
print(i)
# async for 在推导式中 result = [i async for i in aiter() if i % 2] # await 表达式在推导式中 result = [await fun() for fun in funcs if await condition()]
无需元类即可定制子类创建:
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 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
def __set_name__(self, owner, name): # 新增!
self.name = name
class Model:
int_field = IntField() # __set_name__ 自动被调用
os.PathLike 接口让所有标准库函数原生支持 pathlib.Path:
import pathlib
# open() 直接接受 Path 对象
with open(pathlib.Path("README")) as f:
content = f.read()
# os.path 系列函数均支持
os.path.splitext(pathlib.Path("some_file.txt")) # ('some_file', '.txt')
os.path.join("/a/b", pathlib.Path("c")) # '/a/b/c'
os.fspath(pathlib.Path("file.txt")) # 'file.txt'
新实现使用紧凑表示,内存占用减少 20%-25%:
# 注意:此时顺序保证仍被视为实现细节 # 3.7 起正式成为语言规范的一部分
| 改进 | 说明 |
|---|---|
| 文件系统编码 → UTF-8 | sys.getfilesystemencoding() 默认返回 'utf-8' |
| 控制台编码 → UTF-8 | sys.stdin/stdout/stderr 默认 UTF-8 |
| 长路径支持 | python.exe 标记为 long-path aware,260 字符限制解除 |
# 恢复旧行为 PYTHONLEGACYWINDOWSFSENCODING=1 PYTHONLEGACYWINDOWSSTDIO=1
专为密码学安全随机数设计,替代 random 用于安全场景:
import secrets # 生成安全令牌 token = secrets.token_hex(16) # 32 位十六进制字符串 token = secrets.token_urlsafe(32) # URL 安全字符串 # 生成随机整数(指定范围) code = secrets.randbelow(10000) # 0-9999 # 比较安全字符串(防时序攻击) secrets.compare_digest(a, b)
3.6 起 asyncio 不再是临时 API,成为正式稳定模块:
# 新增功能 asyncio.run_coroutine_threadsafe(coro, loop) # 从其他线程提交协程 loop.create_future() # 创建 Future loop.get_exception_handler() # 获取异常处理器 loop.connect_accepted_socket() # 接受外部连接 loop.shutdown_asyncgens() # 关闭异步生成器
性能提升: Future 和 Task 的 C 实现使 asyncio 代码提速 30%。
from enum import Enum, Flag, auto
# 位域枚举
class Perm(Flag):
R = auto()
W = auto()
X = auto()
# 自动赋值
class Color(Enum):
red = auto() # 1
blue = auto() # 2
green = auto() # 3
import hashlib # BLAKE2 hashlib.blake2b(data) hashlib.blake2s(data) # SHA-3 hashlib.sha3_256(data) hashlib.sha3_512(data) # 密码学安全 KDF hashlib.scrypt(password, salt=salt, n=16384, r=8, p=1)
from datetime import datetime, timezone, timedelta
Eastern = timezone(timedelta(hours=-5), 'EST')
for i in range(4):
u = datetime(2016, 11, 6, 4 + i, tzinfo=timezone.utc)
t = u.astimezone(Eastern)
print(t.time(), t.tzname(), t.fold)
# 04:00 EDT 0
# 01:00 EDT 0
# 01:00 EST 1 ← fold=1 表示第二个(秋令时回拨)
# 02:00 EST 0
from collections.abc import Collection, Reversible, AsyncGenerator # Collection: 有长度的可迭代容器 # Reversible: 支持 __reversed__ 的可迭代对象 # AsyncGenerator: 异步生成器
import cmath cmath.tau # τ = 2π cmath.inf # 正无穷(复数) cmath.nan # 非数字(复数) cmath.infj # 复数正无穷 (inf+0j) cmath.nanj # 复数 NaN (nan+0j)
try:
import something
except ModuleNotFoundError: # ImportError 的子类
...
# decimal 新方法
Decimal('-3.14').as_integer_ratio() # (-157, 50)
# datetime 新参数
datetime.combine(date, time, tzinfo=tz) # 支持 tzinfo
datetime.isoformat(timespec='milliseconds') # 精度控制
# typing 反转 getfullargspec 废弃
# inspect.signature() 报告隐式参数 implicit0
# contextlib.AbstractContextManager
# tracemalloc 大幅改进(用于 ResourceWarning)
# email API 稳定化(EmailMessage)
# json 支持二进制输入
# 调试模式:在释放内存中填充 0xDB,检测缓冲区溢出 python -X dev # 或 PYTHONMALLOC=debug # 强制使用系统 malloc PYTHONMALLOC=malloc python app.py
./configure --with-dtrace # 探测事件:函数调用/返回、GC 开始/结束、执行行号
为 JIT 调试器提供 C 级别接口拦截帧求值。
global/nonlocal 必须出现在首行(3.5 是 SyntaxWarning,3.6 提升为 SyntaxError)None 表示操作不可用class NotIterable:
__iter__ = None # 此类不可迭代
[Previous line repeated {count} more times]| 场景 | 说明 |
|---|---|
| 类属性定义顺序 | __dict__ 保留定义顺序 |
| **kwargs 参数顺序 | 按传入顺序排列 |
._pth 文件支持隔离模式python36.zip 可作为 PYTHONHOME 地标Python 3.6 的核心亮点:
1_000_000 提升大数字可读性name: str = "foo" 类属性标注async def 中可同时 yield 和 await__init_subclass__ — 无需元类定制子类创建__set_name__ — 描述符感知自身属性名secrets 模块 — 密码学安全随机数Python 3.6 是一个语法体验大幅提升的版本。f-strings 彻底改变了字符串格式化的写法,变量注解语法让类型标注覆盖到所有变量级别,而异步生成器的引入则补完了 asyncio 生态的最后一块拼图。同时字典实现的内存优化和 Windows UTF-8 编码的改进也为后续版本奠定了坚实的基础。
参考:Python 3.6 官方文档 - What’s New