python 3.8的新功能¶
- 编辑
雷蒙德·赫廷格
本文将解释Python 3.8与3.7相比的新特性。有关详细信息,请参见 changelog .
总结——发布亮点¶
新特点¶
赋值表达式¶
有新的语法 :=
将值作为较大表达式的一部分分配给变量的。它被亲切地称为“海象操作员”,因为它类似于 the eyes and tusks of a walrus .
在本例中,赋值表达式有助于避免调用 len()
两次::
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
在正则表达式匹配过程中,如果需要匹配对象两次,一次用于测试是否发生匹配,另一次用于提取子组,则会产生类似的好处:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0
对于while循环,该运算符也很有用,while循环计算值以测试循环终止,然后在循环主体中再次需要相同的值:
# Loop over fixed length blocks
while (block := f.read(256)) != '':
process(block)
另一个激励性用例出现在列表理解中,其中表达式体中还需要在过滤条件下计算的值:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
尽量限制使用walrus操作符来清理减少复杂性和提高可读性的案例。
见 PEP 572 完整描述。
(艾米丽·莫豪斯在 bpo-35224 )
仅位置参数¶
有一个新的函数参数语法 /
以指示某些函数参数必须按位置指定,并且不能用作关键字参数。这是由 help()
对于用Larry Hastings注释的C函数 Argument Clinic 工具。
在下面的示例中,参数 a 和 b 只是位置性的,而 c 或 d 可以是位置或关键字,并且 e 或 f 必须是关键字:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
以下是有效的调用:
f(10, 20, 30, d=40, e=50, f=60)
但是,这些调用无效:
f(10, b=20, c=30, d=40, e=50, f=60) # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60) # e must be a keyword argument
这种表示法的一个用例是,它允许纯Python函数完全模拟现有C编码函数的行为。例如,内置的 divmod()
函数不接受关键字参数:
def divmod(a, b, /):
"Emulate the built in divmod() function"
return (a // b, a % b)
另一个用例是在参数名没有帮助时排除关键字参数。例如,内置 len()
函数具有签名 len(obj, /)
. 这就排除了一些尴尬的呼叫,例如:
len(obj='hello') # The "obj" keyword argument impairs readability
仅将参数标记为位置参数的另一个好处是,它允许在将来更改参数名称,而不会有破坏客户机代码的风险。例如,在 statistics
模块,参数名 dist 将来可能会改变。这是通过以下功能规范实现的:
def quantiles(dist, /, *, n=4, method='exclusive')
...
因为左边的参数 /
不作为可能的关键字公开,参数名称仍可以在中使用 **kwargs
::
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3) # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
这大大简化了需要接受任意关键字参数的函数和方法的实现。例如,下面是 collections
模块:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
# Note "iterable" is a possible keyword argument
见 PEP 570 完整描述。
(Pablo Galindo在 bpo-36540 )
编译字节码文件的并行文件系统缓存¶
新的 PYTHONPYCACHEPREFIX
设置(也可用作 -X
pycache_prefix
)将隐式字节码缓存配置为使用单独的并行文件系统树,而不是默认值 __pycache__
每个源目录中的子目录。
缓存的位置报告在 sys.pycache_prefix
(None
指示中的默认位置 __pycache__
子目录)。
(由Carl Meyer于 bpo-33499 )
调试生成使用与发布生成相同的ABI¶
Python现在使用相同的ABI,无论它是在发布模式还是调试模式下构建的。在Unix上,当Python在调试模式下构建时,现在可以加载在发布模式下构建的C扩展和使用稳定ABI构建的C扩展。
发布版本和调试版本现在与ABI兼容:定义 Py_DEBUG
宏不再意味着 Py_TRACE_REFS
宏,它引入了唯一的ABI不兼容。这个 Py_TRACE_REFS
宏,它添加了 sys.getobjects()
函数和 PYTHONDUMPREFS
环境变量,可以使用 ./configure --with-trace-refs
生成选项。(由Victor Stinner在 bpo-36465 )
在Unix上,除了Android和Cygwin外,C扩展不再链接到libpython。现在,静态链接的Python可以加载使用共享库Python构建的C扩展。(由Victor Stinner在 bpo-21536 )
在UNIX上,当以调试模式构建python时,import现在还查找以发布模式编译的C扩展和用稳定ABI编译的C扩展。(由Victor Stinner在 bpo-36722 )
要将python嵌入到应用程序中,需要 --embed
选项必须传递给 python3-config --libs --embed
得到 -lpython3.8
(将应用程序链接到libpython)。要同时支持3.8及以上版本,请尝试 python3-config --libs --embed
首先,然后退到 python3-config --libs
(没有) --embed
)如果上一个命令失败。
添加pkg配置 python-3.8-embed
将python嵌入应用程序的模块: pkg-config python-3.8-embed --libs
包括 -lpython3.8
. 要同时支持3.8及以上版本,请尝试 pkg-config python-X.Y-embed --libs
首先,然后退到 pkg-config python-X.Y --libs
(没有) --embed
)如果上一个命令失败(替换 X.Y
使用python版本)。
另一方面, pkg-config python3.8 --libs
不再包含 -lpython3.8
. C扩展不能链接到libpython(android和cygwin除外,它们的情况由脚本处理);此更改是有意向后不兼容的。(由Victor Stinner在 bpo-36721 )
f字符串支持 =
用于自记录表达式和调试¶
增加了一个 =
说明符到 f-string s、 f字符串,如 f'{{expr=}}'
将展开到表达式的文本、等号,然后是求值表达式的表示形式。例如:
>>> user = 'eric_idle'
>>> member_since = date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
通常 f-string format specifiers 允许对表达式结果的显示方式进行更多控制:
>>> delta = date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
这个 =
说明符将显示整个表达式,以便可以显示计算:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
(埃里克诉史密斯和拉里·黑斯廷斯在 bpo-36817 )
PEP 578:Python运行时审计挂钩¶
PEP添加了一个审计钩子和已验证的开放钩子。两者都可以从Python和本机代码中获得,允许使用纯Python代码编写的应用程序和框架利用额外的通知,同时还允许嵌入程序或系统管理员在始终启用审计的情况下部署Python构建。
见 PEP 578 详细信息。
PEP 587:python初始化配置¶
这个 PEP 587 添加一个新的C API来配置python初始化,从而对整个配置提供更好的控制和更好的错误报告。
新结构:
新功能:
PyConfig_Clear()
PyConfig_InitIsolatedConfig()
PyConfig_InitPythonConfig()
PyConfig_Read()
PyConfig_SetArgv()
PyConfig_SetBytesArgv()
PyConfig_SetBytesString()
PyConfig_SetString()
PyPreConfig_InitIsolatedConfig()
PyPreConfig_InitPythonConfig()
PyStatus_Error()
PyStatus_Exception()
PyStatus_Exit()
PyStatus_IsError()
PyStatus_IsExit()
PyStatus_NoMemory()
PyStatus_Ok()
PyWideStringList_Append()
PyWideStringList_Insert()
Py_ExitStatusException()
这个政治公众人物还补充说 _PyRuntimeState.preconfig
(PyPreConfig
类型)和 PyInterpreterState.config
(PyConfig
类型)这些内部结构的字段。 PyInterpreterState.config
成为新的引用配置,替换全局配置变量和其他私有变量。
见 Python Initialization Configuration 用于文档。
见 PEP 587 完整描述。
(由Victor Stinner在 bpo-36763 )
PEP 590:Vectorcall:CPython的快速调用协议¶
矢量调用协议 添加到Python/C API中。它的目的是将已经为各种类完成的现有优化形式化。任何实现可调用的静态类型都可以使用此协议。
这是暂时的。目的是在Python3.9中完全公开它。
见 PEP 590 完整描述。
(由杰罗恩德梅耶,马克香农和彼得维克托林在 bpo-36974 )
带带外数据缓冲区的pickle协议5¶
什么时候? pickle
用于在python进程之间传输大数据,为了利用多核或多机处理,通过减少内存副本以及可能应用自定义技术(如数据相关压缩)来优化传输非常重要。
这个 pickle
协议5引入了对带外缓冲区的支持,其中 PEP 3118 -根据通信层的判断,兼容数据可以与主pickle流分开传输。
见 PEP 574 完整描述。
(由Antoine Pitrou在 bpo-36785 )
其他语言更改¶
A
continue
声明在中是非法的finally
由于实现有问题而导致的子句。在python 3.8中,这个限制被解除了。(Serhiy Storchaka在 bpo-32489 )这个
bool
,int
和fractions.Fraction
类型现在有一个as_integer_ratio()
这种方法在float
和decimal.Decimal
. 这个小的API扩展使得可以编写numerator, denominator = x.as_integer_ratio()
并让它跨多个数字类型工作。(作者:Lisa Roach in) bpo-33073 还有雷蒙德·赫廷格 bpo-37819 )建筑工人
int
,float
和complex
现在将使用__index__()
特殊方法(如有)和相应方法__int__()
,__float__()
或__complex__()
不可用。(Serhiy Storchaka在 bpo-20092 )增加了对
\N{{name}}
逃逸regular expressions
::>>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') >>> int(copyright_year_pattern.search(notice).group(1)) 2019
(作者:Jonathan Eunice和Serhiy Storchaka bpo-30688 )
dict和dictview现在可以按相反的插入顺序使用
reversed()
. (R_mi Lapeyre在 bpo-33462 )函数调用中关键字名称所允许的语法受到了进一步的限制。特别地,
f((keyword)=arg)
不再允许。它从未打算在关键字参数赋值项的左侧允许超过一个裸名称。(本杰明·彼得森在 bpo-34641 )广义可拓解包
yield
和return
语句不再需要括括号。这就带来了 产量 和 返回 语法与正常赋值语法更加一致:>>> def parse(family): lastname, *members = family.split() return lastname.upper(), *members >>> parse('simpsons homer marge bart lisa maggie') ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
(作者大卫·卡斯伯特和乔丹·查普曼 bpo-32117 )
当代码中缺少逗号时,例如
[(10, 20) (30, 40)]
,编译器将显示SyntaxWarning
有个有用的建议。这比仅仅拥有一个TypeError
表示第一个元组不可调用。(塞尔希斯托查卡在 bpo-15248 )子类之间的算术运算
datetime.date
或datetime.datetime
和datetime.timedelta
对象现在返回子类的一个实例,而不是基类。这还影响其实现(直接或间接)使用的操作的返回类型datetime.timedelta
算术,如astimezone()
. (由Paul Ganssle在 bpo-32417 )当python解释器被ctrl-c(sigint)中断时,
KeyboardInterrupt
未捕获异常,python进程现在通过sigint信号或使用正确的退出代码退出,这样调用进程就可以检测到它是由于ctrl-c而死亡的。posix和windows上的shell使用此方法在交互会话中正确终止脚本。(由Google通过Gregory P.Smith在 bpo-1054041 )一些高级的编程风格需要更新
types.CodeType
现有函数的对象。由于代码对象是不可变的,因此需要创建一个新的代码对象,一个基于现有代码对象建模的代码对象。有19个参数,这有点乏味。现在,新的replace()
方法使创建具有少量更改参数的克隆成为可能。下面是一个改变
statistics.mean()
防止 data 用作关键字参数的参数:>>> from statistics import mean >>> mean(data=[10, 20, 90]) 40 >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1) >>> mean(data=[10, 20, 90]) Traceback (most recent call last): ... TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'
(由Victor Stinner在 bpo-37032 )
对于整数,三参数形式的
pow()
函数现在允许指数为负,如果基数相对于模量为素数。然后,当指数为-1
,以及其他负指数的逆幂。例如,要计算 modular multiplicative inverse 在38的137模中,写:>>> pow(38, -1, 137) 119 >>> 119 * 38 % 137 1
模逆产生于 linear Diophantine equations . 例如,要查找
4258𝑥 + 147𝑦 = 369
,首先重写为4258𝑥 ≡ 369 (mod 147)
然后解决:>>> x = 369 * pow(4258, -1, 147) % 147 >>> y = (4258 * x - 369) // -147 >>> 4258 * x + 147 * y 369
(马克·狄金森在 bpo-36027 )
Dict理解已与Dict文本同步,以便首先计算键,然后计算值:
>>> # Dict comprehension >>> cast = {input('role? '): input('actor? ') for i in range(2)} role? King Arthur actor? Chapman role? Black Knight actor? Cleese >>> # Dict literal >>> cast = {input('role? '): input('actor? ')} role? Sir Robin actor? Eric Idle
保证的执行顺序对于赋值表达式很有帮助,因为键表达式中赋值的变量将在值表达式中可用:
>>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald'] >>> {(n := normalize('NFC', name)).casefold() : n for name in names} {'martin von löwis': 'Martin von Löwis', 'łukasz langa': 'Łukasz Langa', 'walter dörwald': 'Walter Dörwald'}
(作者:海斯勒 bpo-35224 )
这个
object.__reduce__()
方法现在可以返回两到六个元素长度的元组。以前,五个是极限。新的可选第六个元素是一个(obj, state)
签名。这允许直接控制特定对象的状态更新行为。如果没有 None ,此可调用项的优先级将高于对象的__setstate__()
方法。(Pierre Glaser和Olivier Grisel在 bpo-35900 )
新模块¶
新的
importlib.metadata
模块为从第三方包读取元数据提供(临时)支持。例如,它可以提取已安装包的版本号、入口点列表等:>>> # Note following example requires that the popular "requests" >>> # package has been installed. >>> >>> from importlib.metadata import version, requires, files >>> version('requests') '2.22.0' >>> list(requires('requests')) ['chardet (<3.1.0,>=3.0.2)'] >>> list(files('requests'))[:5] [PackagePath('requests-2.22.0.dist-info/INSTALLER'), PackagePath('requests-2.22.0.dist-info/LICENSE'), PackagePath('requests-2.22.0.dist-info/METADATA'), PackagePath('requests-2.22.0.dist-info/RECORD'), PackagePath('requests-2.22.0.dist-info/WHEEL')]
(由Barry Warsaw和Jason R.Coombs在 bpo-34632 )
改进的模块¶
AST¶
AST节点现在有 end_lineno
和 end_col_offset
属性,提供节点末端的精确位置。(这仅适用于 lineno
和 col_offset
属性。)
新功能 ast.get_source_segment()
返回特定ast节点的源代码。
(伊万·列夫基夫斯基于 bpo-33416 )
这个 ast.parse()
函数有一些新标志:
mode='func_type'
可用于分析 PEP 484 “签名类型注释”(返回函数定义ast节点);feature_version=(3, N)
允许指定较早的Python3版本。例如,feature_version=(3, 4)
会治疗async
和await
作为非保留字。
(作者:Guido van Rossum in) bpo-35766 )
asyncio¶
asyncio.run()
已从临时API升级为稳定API。此函数可用于执行 coroutine 并在自动管理事件循环时返回结果。例如::
import asyncio
async def main():
await asyncio.sleep(0)
return 42
asyncio.run(main())
这是 粗略地 相当于:
import asyncio
async def main():
await asyncio.sleep(0)
return 42
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
finally:
asyncio.set_event_loop(None)
loop.close()
实际的实现要复杂得多。因此, asyncio.run()
应该是运行异步程序的首选方式。
(由Yury Selivanov在 bpo-32314 )
运行 python -m asyncio
启动本机异步复制。这允许对具有顶级 await
. 不再需要直接打电话 asyncio.run()
这将在每次调用时生成一个新的事件循环:
$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello
(由Yury Selivanov在 bpo-37028 )
例外 asyncio.CancelledError
现在继承自 BaseException
而不是 Exception
不再继承 concurrent.futures.CancelledError
. (由Yury Selivanov在 bpo-32528 )
在Windows上,默认的事件循环现在是 ProactorEventLoop
. (由Victor Stinner在 bpo-34687 )
ProactorEventLoop
现在还支持UDP。(由Adam Meily和Andrew Svetlov在 bpo-29883 )
ProactorEventLoop
现在可以被中断 KeyboardInterrupt
(“ctrl+c”)。(Vladimir Matveev在 bpo-23057 )
补充 asyncio.Task.get_coro()
在一个 asyncio.Task
. (亚历克斯·格伦霍姆在 bpo-36999 )
现在可以通过传递 name
关键字参数 asyncio.create_task()
或 create_task()
事件循环方法,或通过调用 set_name()
任务对象的方法。任务名称在 repr()
的输出 asyncio.Task
也可以使用 get_name()
方法。(亚历克斯·格伦霍姆在 bpo-34270 )
为添加了支持 Happy Eyeballs 到 asyncio.loop.create_connection()
. 要指定行为,添加了两个新参数: happy_eyeballs_delay 和 交错 . 开心眼球算法通过尝试同时使用IPv4和IPv6连接来提高支持IPv4和IPv6的应用程序的响应能力。(驻英国大使托斯特罗伊德供稿) bpo-33530 )
建筑材料¶
这个 compile()
内置的已改进以接受 ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
旗帜。当这个新的旗子通过时, compile()
将允许顶级 await
, async for
和 async with
通常被认为是无效语法的构造。用标记的异步代码对象 CO_COROUTINE
然后可以返回标志。(马蒂亚斯·布森尼尔在 bpo-34616 )
收藏¶
这个 _asdict()
方法 collections.namedtuple()
现在返回 dict
而不是 collections.OrderedDict
. 这是因为自Python3.7以来,常规的dict已经保证了排序。如果 OrderedDict
如果需要,建议的补救措施是将结果强制转换为所需类型: OrderedDict(nt._asdict())
. (由Raymond Hettinger在 bpo-35864 )
cProfile¶
这个 cProfile.Profile
类现在可以用作上下文管理器。通过运行以下命令分析代码块:
import cProfile
with cProfile.Profile() as profiler:
# code to be profiled
...
(作者:斯科特·桑德森 bpo-29235 )
csv¶
这个 csv.DictReader
现在返回的实例 dict
而不是 collections.OrderedDict
. 该工具现在速度更快,占用的内存更少,同时仍保持字段顺序。(作者:迈克尔·塞利克 bpo-34003 )
curses¶
为基础ncurses库添加了一个保存结构化版本信息的新变量: ncurses_version
. (Serhiy Storchaka在 bpo-31680 )
C型¶
在Windows上, CDLL
子类现在接受 温德模式 用于指定基础标志的参数 LoadLibraryEx
打电话。默认标志设置为仅从受信任位置加载dll依赖项,包括存储dll的路径(如果使用完整或部分路径加载初始dll)和由添加的路径 add_dll_directory()
. (史蒂夫道尔供稿 bpo-36085 )
日期时间¶
添加了新的备用构造函数 datetime.date.fromisocalendar()
和 datetime.datetime.fromisocalendar()
,哪个构造 date
和 datetime
分别来自ISO year、week number和weekday的对象;它们与每个类的 isocalendar
方法。(由Paul Ganssle在 bpo-36004 )
功能工具¶
functools.lru_cache()
现在可以用作直接的装饰器,而不是作为返回装饰器的函数。所以现在这两个都支持:
@lru_cache
def f(x):
...
@lru_cache(maxsize=256)
def f(x):
...
(由Raymond Hettinger在 bpo-36772 )
增加了一个新的 functools.cached_property()
decorator,用于实例生命周期中缓存的计算属性。:
import functools
import statistics
class Dataset:
def __init__(self, sequence_of_numbers):
self.data = sequence_of_numbers
@functools.cached_property
def variance(self):
return statistics.variance(self.data)
(由Carl Meyer于 bpo-21145 )
增加了一个新的 functools.singledispatchmethod()
将方法转换为 generic functions 使用 single dispatch ::
from functools import singledispatchmethod
from contextlib import suppress
class TaskManager:
def __init__(self, tasks):
self.tasks = list(tasks)
@singledispatchmethod
def discard(self, value):
with suppress(ValueError):
self.tasks.remove(value)
@discard.register(list)
def _(self, tasks):
targets = set(tasks)
self.tasks = [x for x in self.tasks if x not in targets]
(作者伊森·史密斯 bpo-32380 )
GC¶
get_objects()
现在可以接收可选 一代 表示从中获取对象的生成的参数。(Pablo Galindo于 bpo-36016 )
获取文本¶
补充 pgettext()
以及它的变体。(由Franz Glasner、Ric Araujo和Cheryl Sabella在 bpo-2504 )
GZIP¶
增加了 mtime 参数到 gzip.compress()
用于可复制输出。(郭慈teo于年供稿) bpo-34898 )
A BadGzipFile
现在引发异常而不是 OSError
对于某些类型的无效或损坏的gzip文件。(由菲利普·格鲁兹基、米歇尔·奥尔和扎克利·斯皮茨在 bpo-6584 )
空闲和空闲¶
N行上的输出(默认为50)被压缩为一个按钮。n可以在设置对话框的常规页面的pyshell部分更改。用鼠标右键单击输出可以压缩的行更少,但也可能更长。通过双击按钮或右键单击按钮进入剪贴板或单独的窗口,可以就地扩展压缩输出。(由Tal Einat在 bpo-1529353 )
将“运行自定义”添加到“运行”菜单以运行具有自定义设置的模块。输入的任何命令行参数都将添加到sys.argv。它们也会重新出现在下一次自定义运行的框中。也可以抑制正常的Shell主模块重启。(由Cheryl Sabella、Terry Jan Reedy和其他 bpo-5680 和 bpo-37627 )
为空闲编辑器窗口添加了可选行号。除非在“配置”对话框的“常规”选项卡中另有设置,否则窗口将不带行号打开。现有窗口的行号将显示并隐藏在“选项”菜单中。(Tal Einat和Saimadhav Heblikar在 bpo-17535 )
OS本机编码现在用于Python字符串和Tcl对象之间的转换。这允许IDLE处理emoji和其他非BMP字符。这些字符可以显示、复制并粘贴到剪贴板或从剪贴板粘贴。将字符串从Tcl转换到Python再转换回Python现在永远不会失败。(许多人为此工作了八年,但这个问题终于在年由塞尔希斯托尔恰卡解决了。) bpo-13153 )
3.8.1新增:
关闭闪烁选项。(作者:Zackery Spytz bpo-4603 )
Escape键现在关闭空闲完成窗口。(作者:Johnny Najera bpo-38944 )
以上更改已返回到3.7维护版本。
向模块名称完成列表添加关键字。(作者:Terry J.Reedy bpo-37765 )
检查¶
这个 inspect.getdoc()
函数现在可以找到 __slots__
如果该属性是 dict
其中值是docstring。这提供了类似于我们已有的文档选项 property()
, classmethod()
和 staticmethod()
::
class AudioClip:
__slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
'duration': 'in seconds, rounded up to an integer'}
def __init__(self, bit_rate, duration):
self.bit_rate = round(bit_rate / 1000.0, 1)
self.duration = ceil(duration)
(由Raymond Hettinger在 bpo-36326 )
输入输出¶
在开发模式下 (-X
env
)在调试构建中, io.IOBase
如果 close()
方法失败。默认情况下,在发布版本中会自动忽略该异常。(由Victor Stinner在 bpo-18748 )
迭代工具¶
这个 itertools.accumulate()
函数添加了一个选项 最初的 用于指定初始值的关键字参数:
>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]
(作者:Lisa Roach in) bpo-34659 )
json.tool¶
添加选项 --json-lines
将每个输入行解析为单独的JSON对象。(洪伟鹏供稿 bpo-31553 )
登录中¶
增加了一个 力 关键字参数 logging.basicConfig()
如果设置为true,则在执行其他参数指定的配置之前,将删除并关闭附加到根记录器的任何现有处理程序。
这解决了一个长期存在的问题。一次伐木工人或 基本配置() 已经打过电话,后来打给 基本配置() 被默默地忽略了。这使得使用交互式提示符或Jupyter笔记本更新、试验或教授各种日志配置选项变得困难。
(Raymond Hettinger建议,Dong hee Na实施,Vinay Sajip in审核) bpo-33897 )
数学¶
新增功能 math.dist()
用于计算两点之间的欧氏距离。(由Raymond Hettinger在 bpo-33089 )
扩大了 math.hypot()
函数处理多个维度。以前,它只支持二维案例。(由Raymond Hettinger在 bpo-33089 )
新增功能, math.prod()
,类似于 sum()
返回“start”值(默认值:1)乘以iterable的数字:
>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126
(Pablo Galindo在 bpo-35606 )
增加了两个新的组合函数 math.perm()
和 math.comb()
::
>>> math.perm(10, 3) # Permutations of 10 things taken 3 at a time
720
>>> math.comb(10, 3) # Combinations of 10 things taken 3 at a time
120
(由Yash Aggarwal、Keller Fuchs、Serhiy Storchaka和Raymond Hettinger在 bpo-37128 , bpo-37178 和 bpo-35431 )
添加了一个新函数 math.isqrt()
用于计算不转换为浮点的精确整数平方根。新函数支持任意大的整数。它比 floor(sqrt(n))
但比 math.sqrt()
::
>>> r = 650320427
>>> s = r ** 2
>>> isqrt(s - 1) # correct
650320426
>>> floor(sqrt(s - 1)) # incorrect
650320427
(马克·狄金森在 bpo-36887 )
函数 math.factorial()
不再接受非int-like的参数。(Pablo Galindo在 bpo-33083 )
MMAP¶
这个 mmap.mmap
班级现在有一个 madvise()
访问的方法 madvise()
系统调用。(由扎克利·斯皮茨在 bpo-32941 )
多重处理¶
新增 multiprocessing.shared_memory
模块。(作者:Davin Potts in) bpo-35813 )
在MacOS上, 产卵 默认情况下,现在使用Start方法。(由Victor Stinner在 bpo-33725 )
操作系统¶
新增功能 add_dll_directory()
在Windows上,用于在导入扩展模块或使用加载DLL时为本机依赖项提供其他搜索路径 ctypes
. (史蒂夫道尔供稿 bpo-36085 )
一个新的 os.memfd_create()
添加了函数来包装 memfd_create()
系统调用。(由扎克利·斯皮茨和克里斯蒂安·海姆斯在 bpo-26836 )
在Windows上,处理重分析点(包括符号链接和目录连接)的大部分手动逻辑已委托给操作系统。明确地, os.stat()
现在将遍历操作系统支持的任何内容,而 os.lstat()
将只打开标识为“名称代理”的重新分析点,而打开其他的 os.stat()
. 在所有情况下, stat_result.st_mode
只会有 S_IFLNK
为符号链接而不是其他类型的重分析点设置。要识别其他类型的重新分析点,请检查新的 stat_result.st_reparse_tag
属性。
在Windows上, os.readlink()
现在可以读取目录连接。请注意 islink()
将返回 False
用于目录连接,以及用于检查 islink
首先将继续将连接视为目录,而处理来自 os.readlink()
现在可以将连接视为链接。
(史蒂夫道尔供稿 bpo-37834 )
os.path¶
os.path
返回布尔结果的函数 exists()
, lexists()
, isdir()
, isfile()
, islink()
和 ismount()
现在回来 False
而不是提高 ValueError
或其子类 UnicodeEncodeError
和 UnicodeDecodeError
对于包含在操作系统级别不可显示的字符或字节的路径。(Serhiy Storchaka在 bpo-33721 )
expanduser()
在Windows上,现在更喜欢 USERPROFILE
环境变量且不使用 HOME
,这通常不为常规用户帐户设置。(安东尼·索蒂尔供稿 bpo-36264 )
isdir()
在Windows上不再返回 True
指向不存在的目录的链接。
realpath()
在Windows上,现在解析重新分析点,包括符号链接和目录连接。
(史蒂夫道尔供稿 bpo-37834 )
pathlib¶
pathlib.Path
返回布尔结果的方法 exists()
, is_dir()
, is_file()
, is_mount()
, is_symlink()
, is_block_device()
, is_char_device()
, is_fifo()
, is_socket()
现在回来 False
而不是提高 ValueError
或其子类 UnicodeEncodeError
对于包含OS级别不可显示字符的路径。(Serhiy Storchaka在 bpo-33721 )
补充 pathlib.Path.link_to()
创建指向路径的硬链接。(由Joannah Nanjekye在 bpo-26978 )
泡菜¶
pickle
扩展子类化C优化 Pickler
现在可以通过定义特殊的 reducer_override()
方法。(Pierre Glaser和Olivier Grisel在 bpo-35900 )
普利斯利布¶
新增 plistlib.UID
并支持读写nskeyedarchive编码的二进制plist。(由Jon Janzen在 bpo-26707 )
印记¶
这个 pprint
模块添加了 sort_dicts 多个函数的参数。默认情况下,这些函数在呈现或打印之前继续对词典进行排序。但是,如果 sort_dicts 如果设置为false,则字典将保留插入键的顺序。这对于在调试期间与JSON输入进行比较非常有用。
此外,还有一个方便的新功能, pprint.pp()
就像是 pprint.pprint()
但与 sort_dicts 拖欠 False
::
>>> from pprint import pprint, pp
>>> d = dict(source='input.txt', operation='filter', destination='output.txt')
>>> pp(d, width=40) # Original order
{'source': 'input.txt',
'operation': 'filter',
'destination': 'output.txt'}
>>> pprint(d, width=40) # Keys sorted alphabetically
{'destination': 'output.txt',
'operation': 'filter',
'source': 'input.txt'}
(Rémi Lapeyre in供稿) bpo-30670 )
py_compile¶
py_compile.compile()
现在支持静默模式。(由Joannah Nanjekye在 bpo-22640 )
施莱克斯¶
新的 shlex.join()
函数用作 shlex.split()
. (由Bo Bayles于 bpo-32102 )
舒蒂尔¶
shutil.copytree()
现在接受新的 dirs_exist_ok
关键字参数。(乔希·布朗森在 bpo-20849 )
shutil.make_archive()
现在默认为现代pax(posix.1-2001)格式的新档案馆,以提高可移植性和标准一致性,继承了从相应的变化到 tarfile
模块。(C.A.M.Gerlach在 bpo-30661 )
shutil.rmtree()
在Windows上,现在删除目录连接而不首先递归地删除其内容。(史蒂夫道尔供稿 bpo-37834 )
Socket¶
补充 create_server()
和 has_dualstack_ipv6()
在创建服务器套接字时自动执行所需任务的便利功能,包括在同一套接字上同时接受IPv4和IPv6连接。(吉安波洛·罗多拉于年撰稿) bpo-17561 )
这个 socket.if_nameindex()
, socket.if_nametoindex()
和 socket.if_indextoname()
功能已在Windows上实现。(由扎克利·斯皮茨在 bpo-37007 )
SSL¶
补充 post_handshake_auth
启用和 verify_client_post_handshake()
启动TLS 1.3握手后身份验证。(由Christian Heimes在 bpo-34670 )
统计学¶
补充 statistics.fmean()
作为更快的浮点变量 statistics.mean()
. (由Raymond Hettinger和Steven D'Aprano在 bpo-35904 )
补充 statistics.geometric_mean()
(由Raymond Hettinger在 bpo-27181 )
补充 statistics.multimode()
返回最常见值的列表。(由Raymond Hettinger在 bpo-35892 )
补充 statistics.quantiles()
将数据或分布划分为等概率区间(如四分位数、十分位数或百分位数)。(由Raymond Hettinger在 bpo-36546 )
补充 statistics.NormalDist
,用于创建和操作随机变量的正态分布的工具。(由Raymond Hettinger在 bpo-36018 )
>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
>>> temperature_feb.mean
6.0
>>> temperature_feb.stdev
6.356099432828281
>>> temperature_feb.cdf(3) # Chance of being under 3 degrees
0.3184678262814532
>>> # Relative chance of being 7 degrees versus 10 degrees
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762
>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño # Add in a climate effect
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)
>>> temperature_feb * (9/5) + 32 # Convert to Fahrenheit
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3) # Generate random samples
[7.672102882379219, 12.000027119750287, 4.647488369766392]
系统¶
添加新 sys.unraisablehook()
函数,它可以被重写以控制如何处理“不可评估的异常”。当发生异常时调用它,但Python无法处理它。例如,当析构函数引发异常或在垃圾收集期间 (gc.collect()
)(由Victor Stinner在 bpo-36829 )
tarfile¶
这个 tarfile
模块现在默认为新档案的现代PAX(posix.1-2001)格式,而不是以前的GNU特定格式。这通过标准化和可扩展格式的一致编码(UTF-8)提高了跨平台的可移植性,并提供了其他一些好处。(C.A.M.Gerlach在 bpo-36268 )
线程加工¶
添加新的 threading.excepthook()
处理未绘制的函数 threading.Thread.run()
例外。它可以被重写以控制未捕获的程度 threading.Thread.run()
处理异常。(由Victor Stinner在 bpo-1230540 )
添加新的 threading.get_native_id()
函数和 native_id
属性 threading.Thread
上课。它们返回由内核分配的当前线程的本机完整线程ID。此功能仅在某些平台上可用,请参见 get_native_id
更多信息。(作者杰克·特斯勒 bpo-36084 )
令牌化¶
这个 tokenize
模块现在隐式地发出 NEWLINE
当输入没有尾随新行时提供标记。这种行为现在与C记号赋予器在内部所做的相匹配。(安马尔·阿斯卡尔在 bpo-33899 )
tkinter¶
添加方法 selection_from()
, selection_present()
, selection_range()
和 selection_to()
在 tkinter.Spinbox
类。(朱丽叶·蒙塞尔在 bpo-34829 )
添加的方法 moveto()
在 tkinter.Canvas
类。(朱丽叶·蒙塞尔在 bpo-23831 )
这个 tkinter.PhotoImage
现在上课了 transparency_get()
和 transparency_set()
方法。(由扎克利·斯皮茨在 bpo-25451 )
时间¶
新增时钟 CLOCK_UPTIME_RAW
对于MacOS 10.12。(由Joannah Nanjekye在 bpo-35702 )
typing¶
这个 typing
模块包含了几个新功能:
具有每个键类型的字典类型。见 PEP 589 和
typing.TypedDict
. TypedDict只使用字符串键。默认情况下,每个密钥都必须存在。指定“total=False”以允许密钥是可选的:class Location(TypedDict, total=False): lat_long: tuple grid_square: str xy_coordinate: tuple
文本类型。见 PEP 586 和
typing.Literal
. 文字类型表示参数或返回值被限制为一个或多个特定的文字值:def get_status(port: int) -> Literal['connected', 'disconnected']: ...
“最终”变量、函数、方法和类。见 PEP 591 ,
typing.Final
和typing.final()
. 最后一个限定符指示静态类型检查器限制子类化、重写或重新分配:pi: Final[float] = 3.1415926536
协议定义。见 PEP 544 ,
typing.Protocol
和typing.runtime_checkable()
. 简单的ABCtyping.SupportsInt
现在Protocol
子类。新协议类
typing.SupportsIndex
.新功能
typing.get_origin()
和typing.get_args()
.
unicodedata¶
这个 unicodedata
模块已升级为使用 Unicode 12.1.0 释放。
新功能 is_normalized()
可用于验证字符串是否为特定的正常形式,通常比实际规范化字符串快得多。(作者:Max Belanger、David Euresti和Greg Price bpo-32285 和 bpo-37966 )
单元测试¶
补充 AsyncMock
支持的异步版本 Mock
. 还添加了适当的用于测试的新断言函数。(作者:Lisa Roach in) bpo-26467 )
补充 addModuleCleanup()
和 addClassCleanup()
用于支持清理的UnitTest setUpModule()
和 setUpClass()
. (莉萨·罗奇在 bpo-24412 )
几个mock assert函数现在也会在失败时打印实际调用的列表。(由Petter Strandmark在 bpo-35047 )
unittest
模块获得了对作为测试用例使用的协同程序的支持 unittest.IsolatedAsyncioTestCase
. (由Andrew Svetlov在 bpo-32972 )
例子::
import unittest
class TestRequest(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
self.connection = await AsyncConnection()
async def test_get(self):
response = await self.connection.get("https://example.com")
self.assertEqual(response.status_code, 200)
async def asyncTearDown(self):
await self.connection.close()
if __name__ == "__main__":
unittest.main()
venv¶
venv
现在包括一个 Activate.ps1
用于在PowerShell Core 6.1下激活虚拟环境的所有平台上的脚本。(布雷特·坎农在 bpo-32718 )
韦克里夫¶
由返回的代理对象 weakref.proxy()
现在支持矩阵乘法运算符 @
和 @=
除了其他数字运算符。(马克·狄金森在 bpo-36669 )
XML¶
作为对DTD和外部实体检索的缓解措施, xml.dom.minidom
和 xml.sax
默认情况下,模块不再处理外部实体。(由Christian Heimes在 bpo-17239 )
这个 .find*()
方法在 xml.etree.ElementTree
模块支持通配符搜索,如 {{*}}tag
它忽略了名称空间和 {{namespace}}*
返回给定命名空间中的所有标记。(由Stefan Behnel在 bpo-28238 )
这个 xml.etree.ElementTree
模块提供新功能 –xml.etree.ElementTree.canonicalize()
实现C14N 2.0。(由Stefan Behnel在 bpo-13611 )
的目标对象 xml.etree.ElementTree.XMLParser
无法通过新的回调方法接收命名空间声明事件 start_ns()
和 end_ns()
. 另外, xml.etree.ElementTree.TreeBuilder
可以将目标配置为处理有关注释和处理指令的事件,以将它们包括在生成的树中。(由Stefan Behnel在 bpo-36676 和 bpo-36673 )
xmlrpc¶
xmlrpc.client.ServerProxy
现在支持可选 报头 要随每个请求一起发送的一系列HTTP头的关键字参数。除此之外,这使得从默认的基本身份验证升级到更快的会话身份验证成为可能。(Cédric Krier在 bpo-35153 )
优化¶
这个
subprocess
模块现在可以使用os.posix_spawn()
在某些情况下,可以提高性能。目前,只有在满足所有这些条件的情况下,它才用于MacOS和Linux(使用glibc 2.24或更高版本):close_fds 是假的;
preexec_fn , pass_fds , cwd 和 start_new_session 未设置参数;
这个 可执行文件 路径包含一个目录。
(由Joannah Nanjekye和Victor Stinner在 bpo-35537 )
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
和shutil.move()
在Linux和MacOS上使用特定于平台的“快速复制”系统调用,以便更有效地复制文件。”“快速复制”是指复制操作发生在内核中,避免在python中使用“outdd.write(infd.read())`”中的用户空间缓冲区。在Windows上shutil.copyfile()
使用更大的默认缓冲区大小(1 mib而不是16 kib)和memoryview()
-基于的变量shutil.copyfileobj()
使用。在同一个分区中复制512 mib文件的速度在Linux上约为+26%,在MacOS上为+50%,在Windows上为+40%。此外,CPU周期消耗更少。见 依赖平台的高效复制操作 章节。(吉安波洛·罗多拉于年撰稿) bpo-33671 )shutil.copytree()
使用os.scandir()
函数和依赖于它的所有复制函数使用缓存os.stat()
价值观。复制包含8000个文件的目录的速度在Linux上大约是+9%,在Windows上是+20%,在Windows SMB共享上是+30%。还有os.stat()
系统调用减少了38%,使shutil.copytree()
尤其是在网络文件系统上。(吉安波洛·罗多拉于年撰稿) bpo-33695 )中的默认协议
pickle
模块现在是协议4,在Python3.4中首次引入。与自Python3.0以来提供的协议3相比,它提供了更好的性能和更小的大小。去掉一个
Py_ssize_t
成员来自PyGC_Head
. 所有GC跟踪的对象(例如tuple、list、dict)的大小都减少了4或8个字节。(Inada Naoki在 bpo-33597 )uuid.UUID
现在使用__slots__
以减少其内存占用。(沃特·布尔斯特利和塔尔·艾纳特于 bpo-30977 )改进的性能
operator.itemgetter()
到33%点。优化了参数处理,并将单个非负整数索引的常见情况的快速路径添加到元组中(这是标准库中的典型用例)。(由Raymond Hettinger在 bpo-35664 )加快locale查找速度
collections.namedtuple()
. 它们现在的速度比以前快了两倍多,这使得它们成为Python中最快的实例变量查找形式。(由Raymond Hettinger、Pablo Galindo和Joe Jevnik,Serhiy Storchaka于 bpo-32492 )这个
list
如果输入iterable的长度已知(输入实现),则构造函数不会过度分配内部项缓冲区__len__
)这使得创建的列表平均减少了12%。(由Raymond Hettinger和Pablo Galindo在 bpo-33234 )类变量写入速度增加了一倍。当一个非dunder属性被更新时,有一个不必要的调用来更新slots。(由Stefan Behnel、Pablo Galindo Salgado、Raymond Hettinger、Neil Schemenauer和Serhiy Storchaka在 bpo-36012 )
减少了转换传递给许多内置函数和方法的参数的开销。这使得调用一些简单的内置函数和方法的速度加快了20%-50%。(Serhiy Storchaka在 bpo-23867 , bpo-35582 和 bpo-36127 )
LOAD_GLOBAL
指令现在使用新的“每操作码缓存”机制。现在大约快了40%。(由Yury Selivanov和Inada Naoki在 bpo-26219 )
构建和C API更改¶
违约
sys.abiflags
变成空字符串:m
pymalloc的标志变得无用(具有和不具有pymalloc的构建是ABI兼容的),因此已被删除。(由Victor Stinner在 bpo-36707 )变更示例:
只有
python3.8
程序已安装,python3.8m
程序不存在。只有
python3.8-config
脚本已安装,python3.8m-config
剧本不见了。这个
m
标记已从动态库文件名后缀中删除:标准库中的扩展模块,以及由第三方软件包(如从PYPI下载的软件包)生成和安装的模块。例如,在Linux上,python 3.7后缀.cpython-37m-x86_64-linux-gnu.so
成为.cpython-38-x86_64-linux-gnu.so
在Python 3.8中。
头文件已经重新组织,以便更好地分离不同类型的API:
Include/*.h
应该是可移植的公共稳定C API。Include/cpython/*.h
应该是特定于cpython的不稳定的C API;公共API,前面带有一些私有API_Py
或_PY
.Include/internal/*.h
是私有的内部C API,非常特定于CPython。此API没有向后兼容性保证,不应在CPython之外使用。它只针对非常特殊的需求(如调试程序和概要文件)公开,这些需求必须在不调用函数的情况下访问cpython内部。此API现在由安装make install
.
(由Victor Stinner在 bpo-35134 和 bpo-35081 ,由Eric Snow在Python3.7中发起的工作。)
有些宏已转换为静态内联函数:参数类型和返回类型定义良好,没有特定于宏的问题,变量具有局部作用域。示例:
PyObject_INIT()
,PyObject_INIT_VAR()
私人职能:
_PyObject_GC_TRACK()
,_PyObject_GC_UNTRACK()
,_Py_Dealloc()
(由Victor Stinner在 bpo-35059 )
这个
PyByteArray_Init()
和PyByteArray_Fini()
功能已删除。自从python 2.7.4和python 3.2.0被排除在有限的api(稳定的abi)之外之后,它们什么也没做,也没有被记录下来。(由Victor Stinner在 bpo-35713 )结果
PyExceptionClass_Name()
现在是类型const char *
而不是char *
. (Serhiy Storchaka在 bpo-33818 )二元性
Modules/Setup.dist
和Modules/Setup
已删除。以前,在更新cpython源码树时,必须手动复制Modules/Setup.dist
(在源码树中)到Modules/Setup
(在构建树中)以反映上游的任何更改。这对打包者来说是一个小的好处,但代价是在cpython开发之后开发人员经常遇到麻烦,因为忘记复制文件可能会导致构建失败。现在构建系统总是从
Modules/Setup
在源码树中。我们鼓励那些想要定制该文件的人在cpython的Git分支或作为补丁文件来维护他们的更改,就像他们对源代码树的任何其他更改一样。(由Antoine Pitrou在 bpo-32430 )
将python数字转换为C整数的函数
PyLong_AsLong()
和参数解析函数PyArg_ParseTuple()
使用整数转换格式单位,如'i'
现在将使用__index__()
特殊方法而不是__int__()
,如果有。对于具有__int__()
方法,但没有__index__()
方法(类)Decimal
和Fraction
)PyNumber_Check()
现在将返回1
用于实现对象__index__()
.PyNumber_Long()
,PyNumber_Float()
和PyFloat_AsDouble()
现在也可以使用__index__()
方法(如果可用)。(Serhiy Storchaka在 bpo-36048 和 bpo-20092 )堆分配的类型对象现在将增加其引用计数
PyObject_Init()
(及其并行宏PyObject_INIT
而不是在PyType_GenericAlloc()
. 可能需要调整修改实例分配或释放的类型。(由Eddie Elizondo在 bpo-35810 )新功能
PyCode_NewWithPosOnlyArgs()
允许创建类似PyCode_New()
,但加一个 POSONLYARG计数 用于指示仅位置参数的数目的参数。(Pablo Galindo在 bpo-37221 )Py_SetPath()
现在集sys.executable
到程序完整路径 (Py_GetProgramFullPath()
)而不是程序名 (Py_GetProgramName()
)(由Victor Stinner在 bpo-38234 )
已弃用¶
distutils
bdist_wininst
命令现在已弃用,请使用bdist_wheel
(车轮组件)而不是。(由Victor Stinner在 bpo-37481 )不推荐使用的方法
getchildren()
和getiterator()
在ElementTree
模块现在发出DeprecationWarning
而不是PendingDeprecationWarning
. 它们将在Python3.9中被删除。(Serhiy Storchaka在 bpo-29209 )传递的对象不是
concurrent.futures.ThreadPoolExecutor
到loop.set_default_executor()
已弃用,将在python 3.9中禁用。(Elvis Pranskevichus在 bpo-34075 )这个
__getitem__()
方法xml.dom.pulldom.DOMEventStream
,wsgiref.util.FileWrapper
和fileinput.FileInput
已弃用。这些方法的实现忽略了 指数 参数,并返回下一项。(由Berker Peksag于年出资) bpo-9372 )
这个
typing.NamedTuple
类已弃用_field_types
有利于__annotations__
具有相同信息的属性。(作者雷蒙德·赫廷格 bpo-36320 )ast
类Num
,Str
,Bytes
,NameConstant
和Ellipsis
被视为已弃用,将在将来的Python版本中删除。Constant
应该改为使用。(Serhiy Storchaka在 bpo-32892 )ast.NodeVisitor
方法visit_Num()
,visit_Str()
,visit_Bytes()
,visit_NameConstant()
和visit_Ellipsis()
现在不推荐使用,以后的Python版本中将不会调用。添加visit_Constant()
方法来处理所有常量节点。(塞尔希斯托查卡在 bpo-36917 )这个
asyncio.coroutine()
decorator 已弃用,将在版本3.10中删除。而不是@asyncio.coroutine
使用async def
相反。(安德鲁斯维特洛夫在 bpo-36921 )在
asyncio
,显式传递 loop 参数已被弃用,并将在版本3.10中删除,原因如下:asyncio.sleep()
,asyncio.gather()
,asyncio.shield()
,asyncio.wait_for()
,asyncio.wait()
,asyncio.as_completed()
,asyncio.Task
,asyncio.Lock
,asyncio.Event
,asyncio.Condition
,asyncio.Semaphore
,asyncio.BoundedSemaphore
,asyncio.Queue
,asyncio.create_subprocess_exec()
和asyncio.create_subprocess_shell()
.协程对象的显式传递
asyncio.wait()
已弃用,并将在版本3.11中删除。(Yury Selivanov在 bpo-34790 )以下函数和方法在
gettext
模块:lgettext()
,ldgettext()
,lngettext()
和ldngettext()
. 它们返回已编码的字节,如果转换后的字符串存在编码问题,则可能会出现意外的与Unicode相关的异常。在python 3中使用返回unicode字符串的替代方法要好得多。这些功能已经中断很长时间了。功能
bind_textdomain_codeset()
方法output_charset()
和set_output_charset()
和 代碼集 函数的参数translation()
和install()
也不推荐使用,因为它们只用于l*gettext()
功能。(塞尔希斯托查卡在 bpo-33710 )这个
isAlive()
方法threading.Thread
已弃用。(年董希娜供稿) bpo-35283 )许多采用整型参数的内置函数和扩展函数现在将发出
Decimal
s,Fraction
s和任何其他只能转换为整数的对象(例如,__int__()
方法,但没有__index__()
方法)。在未来的版本中,它们将是错误的。(Serhiy Storchaka在 bpo-36048 )不推荐将以下参数作为关键字参数传递:
func 在里面
functools.partialmethod()
,weakref.finalize()
,profile.Profile.runcall()
,cProfile.Profile.runcall()
,bdb.Bdb.runcall()
,trace.Trace.runfunc()
和curses.wrapper()
.功能 在里面
unittest.TestCase.addCleanup()
.fn 在
submit()
方法concurrent.futures.ThreadPoolExecutor
和concurrent.futures.ProcessPoolExecutor
.回调 在里面
contextlib.ExitStack.callback()
,contextlib.AsyncExitStack.callback()
和contextlib.AsyncExitStack.push_async_callback()
.c 和 打字 在
create()
方法multiprocessing.managers.Server
和multiprocessing.managers.SharedMemoryServer
.obj 在里面
weakref.finalize()
.
在未来的Python版本中,它们将 positional-only . (Serhiy Storchaka在 bpo-36492 )
API和功能删除¶
以下特性和API已从Python3.8中删除:
从Python 3.3开始,从
collections
已弃用,导入应从collections.abc
. 能够从集合中导入在3.8中标记为删除,但已延迟到3.9。(见 bpo-36952 )这个
macpath
python 3.7中不推荐使用的模块已被删除。(由Victor Stinner在 bpo-35471 )函数
platform.popen()
自Python 3.3:use以来一直不推荐使用os.popen()
相反。(由Victor Stinner在 bpo-35345 )函数
time.clock()
自Python 3.3:use以来一直不推荐使用time.perf_counter()
或time.process_time()
相反,根据你的要求,要有明确的行为。(马蒂亚斯·布森尼尔在 bpo-36895 )这个
pyvenv
已删除脚本以支持python3.8 -m venv
以帮助消除关于Python解释器pyvenv
脚本绑定到。(布雷特·坎农在 bpo-25427 )parse_qs
,parse_qsl
和escape
从cgi
模块。在Python3.2或更高版本中,它们已被弃用。它们应该从urllib.parse
和html
而不是模块。filemode
函数从tarfile
模块。自python 3.3以来,它没有被记录和弃用。这个
XMLParser
构造函数不再接受 html 参数。它从未产生过效果,在Python3.4中被弃用。所有其他参数现在都是 keyword-only . (Serhiy Storchaka在 bpo-29209 )“unicode_internal”编解码器已删除。(Inada Naoki在 bpo-36297 )
这个
Cache
和Statement
的对象sqlite3
模块不向用户公开。(由Aviv Palivoda在 bpo-30262 )这个
bufsize
的关键字参数fileinput.input()
和fileinput.FileInput()
由于python 3.6已被删除,它被忽略并弃用。 bpo-36952 (由Matthias Bussonnier提供。)功能
sys.set_coroutine_wrapper()
和sys.get_coroutine_wrapper()
python 3.7中已弃用,已删除; bpo-36933 (由Matthias Bussonnier提供。)
移植到python 3.8¶
本节列出了前面描述的更改和可能需要更改代码的其他错误修复。
python行为的变化¶
产量表达式(两个
yield
和yield from
从句)现在在理解和生成器表达式中是不允许的(最左边的iterable表达式除外)for
条款)。(Serhiy Storchaka在 bpo-10544 )编译器现在生成一个
SyntaxWarning
身份检查时 (is
和is not
)与某些类型的文字(例如字符串、数字)一起使用。在CPython中,这些测试通常是意外工作的,但语言规范并不能保证这些测试有效 (==
和!=
相反。(Serhiy Storchaka在 bpo-34850 )在某些情况下,CPython解释器可以接受异常。在Python3.8中,这种情况很少发生。特别是,从类型字典获取属性时引发的异常不再被忽略。(塞尔希斯托查卡在 bpo-35459 )
远离的
__str__
内置类型的实现bool
,int
,float
,complex
以及标准库中的一些类。他们现在继承了__str__()
从object
. 因此,定义__repr__()
这些类的子类中的方法将影响它们的字符串表示。(塞尔希斯托查卡在 bpo-36793 )在AIX上,
sys.platform
不再包含主版本。它总是'aix'
,而不是'aix3'
…'aix7'
. 由于较旧的Python版本包含版本号,因此建议始终使用sys.platform.startswith('aix')
.(由M.Felt在 bpo-36588 )PyEval_AcquireLock()
和PyEval_AcquireThread()
现在,如果在解释器完成时调用,则终止当前线程,使其与PyEval_RestoreThread()
,Py_END_ALLOW_THREADS()
和PyGILState_Ensure()
. 如果不需要这种行为,请检查_Py_IsFinalizing()
或sys.is_finalizing()
. (作者:Joannah Nanjekye in) bpo-36475 )
python api中的更改¶
这个
os.getcwdb()
函数现在在Windows上使用UTF-8编码,而不是ANSI代码页:请参见 PEP 529 理由是。在Windows上不再推荐使用该函数。(由Victor Stinner在 bpo-37412 )subprocess.Popen
现在可以使用os.posix_spawn()
在某些情况下为了更好的表现。在用于Linux和QEMU用户仿真的Windows子系统上Popen
构造函数使用os.posix_spawn()
不再对“缺少程序”之类的错误引发异常。相反,子进程失败,出现非零returncode
. (由Joannah Nanjekye和Victor Stinner在 bpo-35537 )这个 preexec_fn 论证*
subprocess.Popen
不再与子解释程序兼容。在子解释器中使用参数现在引发RuntimeError
. (艾瑞克·斯诺供稿 bpo-34651 ,由Christian Heimes在 bpo-37951 )这个
imap.IMAP4.logout()
方法不再自动忽略任意异常。(作者:Victor Stinner in) bpo-36348 )函数
platform.popen()
自Python 3.3:use以来一直不推荐使用os.popen()
相反。(由Victor Stinner在 bpo-35345 )这个
statistics.mode()
函数在给定多模数据时不再引发异常。相反,它返回在输入数据中遇到的第一个模式。(由Raymond Hettinger在 bpo-35892 )这个
selection()
方法tkinter.ttk.Treeview
类不再接受参数。在python 3.6中,不赞成将它与更改选择的参数一起使用。使用专门的方法,比如selection_set()
用于更改选择。(Serhiy Storchaka在 bpo-31508 )这个
writexml()
,toxml()
和toprettyxml()
方法xml.dom.minidom
和write()
方法xml.etree
,现在保留用户指定的属性顺序。(Diego Rojas和Raymond Hettinger在 bpo-34160 )A
dbm.dumb
用标志打开的数据库'r'
现在是只读的。dbm.dumb.open()
带旗'r'
和'w'
如果数据库不存在,则不再创建它。(Serhiy Storchaka在 bpo-32749 )这个
doctype()
在的子类中定义的方法XMLParser
将不再被调用并将发出RuntimeWarning
而不是DeprecationWarning
. 定义doctype()
用于处理XML doctype声明的目标上的方法。(Serhiy Storchaka在 bpo-29209 )A
RuntimeError
当自定义元类不提供__classcell__
传递给的命名空间中的项type.__new__
. 一DeprecationWarning
在python 3.6--3.7中发出。(Serhiy Storchaka在 bpo-23722 )这个
cProfile.Profile
类现在可以用作上下文管理器。(由Scott Sanderson在 bpo-29235 )shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
和shutil.move()
使用特定于平台的“快速复制”系统调用(请参见 依赖平台的高效复制操作 部分)。shutil.copyfile()
Windows上的默认缓冲区大小已从16 kib更改为1 mib。这个
PyGC_Head
结构已完全更改。所有触及结构成员的代码都应该重写。(见 bpo-33597 )这个
PyInterpreterState
结构已移动到“内部”头文件中(具体包括/internal/pycore_pystate.h)。不透明的PyInterpreterState
仍然作为公共API(和稳定的ABI)的一部分提供。文档表明结构的字段都不是公共的,所以我们希望没有人使用它们。但是,如果您确实依赖这些私有字段中的一个或多个,并且没有其他选择,请打开BPO问题。我们将帮助您进行调整(可能包括向公共API添加访问函数)。(见 bpo-35886 )这个
mmap.flush()
方法现在返回None
在所有平台下成功并引发错误异常。以前,它的行为依赖于平台:成功时返回非零值;在Windows下,错误时返回零值。成功时返回零值;在Unix下出错时引发异常。(由Berker Peksag于年出资) bpo-2122 )xml.dom.minidom
和xml.sax
默认情况下,模块不再处理外部实体。(由Christian Heimes在 bpo-17239 )从只读中删除密钥
dbm
数据库 (dbm.dumb
,dbm.gnu
或dbm.ndbm
提高error
(dbm.dumb.error
,dbm.gnu.error
或dbm.ndbm.error
)而不是KeyError
. (由张翔于 bpo-33106 )简化了文本的AST。所有常数将表示为
ast.Constant
实例。实例化旧类Num
,Str
,Bytes
,NameConstant
和Ellipsis
将返回的实例Constant
. (Serhiy Storchaka在 bpo-32892 )expanduser()
在Windows上,现在更喜欢USERPROFILE
环境变量且不使用HOME
,这通常不为常规用户帐户设置。(安东尼·索蒂尔供稿 bpo-36264 )例外
asyncio.CancelledError
现在继承自BaseException
而不是Exception
不再继承concurrent.futures.CancelledError
. (由Yury Selivanov在 bpo-32528 )函数
asyncio.wait_for()
现在正确地等待在使用asyncio.Task
. 之前,到达时 超时 ,它被取消并立即返回。(埃尔维斯·普兰斯克维丘斯在 bpo-32751 )函数
asyncio.BaseTransport.get_extra_info()
现在,当“socket”传递给 name 参数。(Yury Selivanov在 bpo-37027 )asyncio.BufferedProtocol
已经升级到稳定的API。
用于加载扩展模块和DLL的dll依赖项
ctypes
现在,在Windows上的解决方案更加安全。只有系统路径、包含dll或pyd文件的目录以及添加了add_dll_directory()
搜索加载时间依赖项。明确地,PATH
当前的工作目录不再使用,对这些目录的修改将不再对正常的DLL解析产生任何影响。如果您的应用程序依赖于这些机制,您应该检查add_dll_directory()
如果它存在,则在加载库时使用它添加dll目录。请注意,Windows 7用户需要确保已安装Windows Update KB2533623(安装程序也会验证这一点)。(史蒂夫道尔供稿 bpo-36085 )与pgen相关的头文件和函数在被纯Python实现替换后被删除。(Pablo Galindo在 bpo-36623 )
types.CodeType
在构造函数的第二个位置有一个新参数( POSONLYARG计数 )支持中定义的仅位置参数的步骤 PEP 570 . 第一个论点( 阿格伯特 )现在表示位置参数(包括仅位置参数)的总数。新的replace()
方法types.CodeType
可以用来证明代码的未来。
C API中的更改¶
这个
PyCompilerFlags
结构有了新的 cf_feature_version 字段。它应该初始化为PY_MINOR_VERSION
. 默认情况下将忽略该字段,并且仅当且仅当PyCF_ONLY_AST
在中设置了标志 cf_flags . (作者:Guido van Rossum in) bpo-35766 )这个
PyEval_ReInitThreads()
函数已从C API中删除。不应显式调用它:使用PyOS_AfterFork_Child()
相反。(由Victor Stinner在 bpo-36728 )在Unix上,除了Android和Cygwin外,C扩展不再链接到libpython。当嵌入python时,
libpython
不得加载RTLD_LOCAL
,但是RTLD_GLOBAL
相反。以前,使用RTLD_LOCAL
,已无法加载未链接到的C扩展libpython
就像标准库的C扩展*shared*
截面Modules/Setup
. (由Victor Stinner在 bpo-21536 )使用
#
解析或构建值时格式的变体(例如PyArg_ParseTuple()
,Py_BuildValue()
,PyObject_CallFunction()
等)PY_SSIZE_T_CLEAN
定义引发DeprecationWarning
现在。将在3.10或4.0中删除。读 分析参数并生成值 细节。(Inada Naoki在 bpo-36381 )堆分配类型的实例(例如使用
PyType_FromSpec()
)保留对其类型对象的引用。增加这些类型对象的引用计数已从PyType_GenericAlloc()
对于更低级的功能,PyObject_Init()
和PyObject_INIT()
. 这使得通过PyType_FromSpec()
行为与托管代码中的其他类类似。静态分配的类型不受影响。
对于绝大多数情况,应该没有副作用。但是,在分配实例后手动增加引用计数的类型(可能是为了解决bug)现在可能成为不朽的。为了避免这种情况,这些类需要在实例释放期间对类型对象调用py_decref。
要将这些类型正确导入3.8,请应用以下更改:
去除
Py_INCREF
在分配实例之后的类型对象上-如果有的话。打电话后可能会发生这种情况PyObject_New()
,PyObject_NewVar()
,PyObject_GC_New()
,PyObject_GC_NewVar()
或任何其他使用PyObject_Init()
或PyObject_INIT()
.例子:
static foo_struct * foo_new(PyObject *type) { foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); if (foo == NULL) return NULL; #if PY_VERSION_HEX < 0x03080000 // Workaround for Python issue 35810; no longer necessary in Python 3.8 PY_INCREF(type) #endif return foo; }
确保所有自定义
tp_dealloc
堆分配类型的函数会减少类型的引用计数。例子:
static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // This was not needed before Python 3.8 (Python issue 35810) Py_DECREF(type); #endif }
(由Eddie Elizondo在 bpo-35810 )
这个
Py_DEPRECATED()
已为MSVC实现宏。宏现在必须放在符号名称之前。例子:
Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
(由扎克利·斯皮茨在 bpo-33407 )
解释器不再假装支持跨功能版本的扩展类型的二进制兼容性。一
PyTypeObject
由第三方扩展模块导出的应该具有当前Python版本中预期的所有插槽,包括tp_finalize
(Py_TPFLAGS_HAVE_FINALIZE
阅读前不再检查tp_finalize
)(由Antoine Pitrou在 bpo-32388 )
功能
PyNode_AddChild()
和PyParser_AddToken()
现在接受另外两个int
参数 end_lineno 和 end_col_offset .这个
libpython38.a
允许mingw工具直接链接到的文件python38.dll
不再包含在常规Windows分发中。如果需要此文件,则可以使用gendef
和dlltool
工具,属于MinGW binutils包的一部分:gendef - python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
安装的位置
pythonXY.dll
将取决于安装选项以及Windows的版本和语言。见 在Windows上使用python 更多信息。结果库应与pythonXY.lib
,通常是libs
python安装下的目录。(史蒂夫道尔供稿 bpo-37351 )
cpython字节码更改¶
解释器循环通过将块堆栈展开到编译器中的逻辑进行了简化。编译器现在发出明确的指令来调整值的堆栈并调用
break
,continue
和return
.删除操作码
BREAK_LOOP
,CONTINUE_LOOP
,SETUP_LOOP
和SETUP_EXCEPT
. 添加了新的操作码ROT_FOUR
,BEGIN_FINALLY
,CALL_FINALLY
和POP_FINALLY
. 改变了END_FINALLY
和WITH_CLEANUP_START
.(由Mark Shannon、Antoine Pitrou和Serhiy Storchaka于 bpo-17611 )
添加了新的操作码
END_ASYNC_FOR
用于处理在等待中的下一项时引发的异常async for
循环。(Serhiy Storchaka在 bpo-33041 )这个
MAP_ADD
现在期望值作为堆栈中的第一个元素,而键作为第二个元素。进行了此更改,因此始终在字典理解中的值之前对密钥进行评估,正如 PEP 572 . (由J_rn Heissler在 bpo-35224 )
演示和工具¶
添加了一个基准脚本,用于计时访问变量的各种方式: Tools/scripts/var_access_benchmark.py
. (由Raymond Hettinger在 bpo-35884 )
以下是自Python3.3以来性能改进的摘要:
Python version 3.3 3.4 3.5 3.6 3.7 3.8
-------------- --- --- --- --- --- ---
Variable and attribute read access:
read_local 4.0 7.1 7.1 5.4 5.1 3.9
read_nonlocal 5.3 7.1 8.1 5.8 5.4 4.4
read_global 13.3 15.5 19.0 14.3 13.6 7.6
read_builtin 20.0 21.1 21.6 18.5 19.0 7.5
read_classvar_from_class 20.5 25.6 26.5 20.7 19.5 18.4
read_classvar_from_instance 18.5 22.8 23.5 18.8 17.1 16.4
read_instancevar 26.8 32.4 33.1 28.0 26.3 25.4
read_instancevar_slots 23.7 27.8 31.3 20.8 20.8 20.2
read_namedtuple 68.5 73.8 57.5 45.0 46.8 18.4
read_boundmethod 29.8 37.6 37.9 29.6 26.9 27.7
Variable and attribute write access:
write_local 4.6 8.7 9.3 5.5 5.3 4.3
write_nonlocal 7.3 10.5 11.1 5.6 5.5 4.7
write_global 15.9 19.7 21.2 18.0 18.0 15.8
write_classvar 81.9 92.9 96.0 104.6 102.1 39.2
write_instancevar 36.4 44.6 45.8 40.0 38.9 35.5
write_instancevar_slots 28.7 35.6 36.1 27.3 26.6 25.7
Data structure read access:
read_list 19.2 24.2 24.5 20.8 20.8 19.0
read_deque 19.9 24.7 25.5 20.2 20.6 19.8
read_dict 19.7 24.3 25.7 22.3 23.0 21.0
read_strdict 17.9 22.6 24.3 19.5 21.2 18.9
Data structure write access:
write_list 21.2 27.1 28.5 22.5 21.6 20.0
write_deque 23.8 28.7 30.1 22.7 21.8 23.5
write_dict 25.9 31.4 33.3 29.3 29.2 24.7
write_strdict 22.9 28.4 29.9 27.5 25.2 23.1
Stack (or queue) operations:
list_append_pop 144.2 93.4 112.7 75.4 74.2 50.8
deque_append_pop 30.4 43.5 57.0 49.4 49.2 42.5
deque_append_popleft 30.8 43.7 57.3 49.7 49.7 42.8
Timing loop:
loop_overhead 0.3 0.5 0.6 0.4 0.3 0.3
基准是在 Intel® Core™ i7-4960HQ processor 运行在 python.org . 基准脚本以纳秒为单位显示计时。
Python 3.8.1中的显著变化¶
由于重大安全问题 reuse_address 参数 asyncio.loop.create_datagram_endpoint()
不再支持。这是因为socket选项的行为 SO_REUSEADDR
在UDP中。有关详细信息,请参阅 loop.create_datagram_endpoint()
. (作者:凯尔·斯坦利、安托万·皮特罗和尤里·塞利万诺夫 bpo-37228 )