本文详细介绍 Python 3.8 中的新功能,以及和与 3.7 相比的一些不同点。
编译的字节码文件的并行文件系统缓存新的 PYTHONPYCACHEPREFIX设置
(也可用 )将隐式字节码缓存配置为使用单独的并行文件系统树,而不是每个源目录中的默认子目录。-X pycache_prefix__pycache_
报告缓存的位置sys.pycache_prefix
(None表示pycache子目录中的默认位置)。
一个continue
说法是非法finally
条款因与实施问题。在Python 3.8中,这一限制被取消了。
该int类型现在具有as_integer_ratio()
与现有float.as_integer_ratio()
方法兼容的新方法。
增加了对\N{name}
的支持。
Dict
和dictviews
现在可以使用反向插入顺序进行迭代 reversed()
。
函数调用中允许关键字名称的语法进一步受到限制。特别是,f((keyword)=arg)不再允许。它从来没有打算在关键字参数赋值术语的左侧允许多于一个裸名称。见bpo-34641。
现在允许Iterable解包,而不使用括号yield 和return语句。(由David Cuthbert和Jordan Chapman在bpo-32117中提供。)
不是有效转义序列的反斜杠字符对DeprecationWarning从Python 3.6开始生成。在Python 3.8中它生成了一个SyntaxWarning代替。(由Serhiy Storchaka供稿于bpo-32912。)
SyntaxWarning在某些情况下,编译器会在元组或列表之前错过逗号时生成。例如:
1data = [ 2 (1, 2, 3) # oops, missing comma! 3 (4, 5, 6) 4]
子类之间的算术运算datetime.date
或 datetime.datetime
与datetime.timedelta
对象现在返回子类的实例,而不是基类。这也会影响其实现(直接或间接)使用datetime.timedelta
算术的操作的返回类型,例如 datetime.datetime.astimezone()
。
当Python解释器被Ctrl-C(SIGINT)中断并且KeyboardInterrupt未捕获到的结果异常时,Python进程现在通过SIGINT信号或正确的退出代码退出,以便调用进程可以检测到它因Ctrl而死亡-C。POSIX和Windows上的shell使用它来正确终止交互式会话中的脚本。
现在的_asdict()方法collections.namedtuple()
返回一个dict而不是一个collections.OrderedDict
。这是有效的,因为自Python 3.7以来,常规dicts已经保证了排序。如果需要额外的功能OrderedDict,建议的补救措施是将结果转换为所需的类型:OrderedDict(nt._asdict())。该unicodedata
模块已升级为使用Unicode 12.0.0 版本。
在Windows上,现在是默认的事件循环ProactorEventLoop。
添加pgettext()
及其变体。
如果该属性是值为docstrings
的位置,该inspect.getdoc()
函数现在可以找到文档字符串。这提供了类似于我们已经有文件的选项,以及:__slots__dictproperty()classmethod()staticmethod()
1class AudioClip: 2 __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place', 3 'duration': 'in seconds, rounded up to an integer'} 4 def __init__(self, bit_rate, duration): 5 self.bit_rate = round(bit_rate / 1000.0, 1) 6 self.duration = ceil(duration)
get_objects()现在可以接收一个可选的生成参数,指示从中获取对象的生成。由Pablo Galindo 提供的 bpo-36016。
添加了mtime参数以gzip.compress()获得可重现的输出。(由Guo Ci Teo在bpo-34898供稿。)
超过N行的输出(默认为50)被压缩到一个按钮。可以在“设置”对话框的“常规”页面的PyShell部分中更改N. 右键单击输出可以挤压更少但可能超长的线条。通过双击按钮或通过右键单击按钮进入剪贴板或单独的窗口,可以扩展压缩输出。(由Tal Einat在bpo-1529353供稿。)
上述更改已被移植到3.7维护版本。
添加选项--json-lines以将每个输入行解析为单独的JSON对象。(由Weipeng Hong在bpo-31553供稿。)
增加math.dist()
了计算两点之间欧氏距离的新函数。
扩展了math.hypot()
处理多个维度的功能。以前,它只支持2-D案例。
添加了新函数,math.prod()
作为类似函数sum() 返回“start”
值(默认值:1)乘以可迭代数字的乘积。
os.path
返回一个布尔值结果类似功能exists()
,lexists()
,isdir()
, isfile()
,islink()
,和ismount()
现在回到False代替升高ValueError
或它的子类 UnicodeEncodeError
,并UnicodeDecodeError
为包含字符或字节在OS级不可表示的路径。
expanduser()
在Windows上现在更喜欢 USERPROFILE 环境变量,不使用 HOME,通常不为常规用户帐户设置。
添加了一个新变量,其中包含底层ncurses
库的结构化版本信息:ncurses_version。
pathlib.Path返回布尔结果类似方法 exists(),is_dir(), is_file(),is_mount(), is_symlink(),is_block_device(), is_char_device(),is_fifo(), is_socket()现在回到False而不是提高 ValueError或它的子类UnicodeEncodeError的包含字符的不可表示在操作系统级别路径。(由Serhiy Storchaka供稿于bpo-33721。)
shutil.copytree()
现在接受一个新的dirs_exist_ok
关键字参数。
添加SSLContext.post_handshake_auth
以启用和 ssl.SSLSocket.verify_client_post_handshake()
启动TLS 1.3握手后身份验证。
添加statistics.fmean()
为更快的浮点变体statistics.mean()
。
添加statistics.multimode()
了返回最常见值的列表。
添加statistics.NormalDist
了一个用于创建和操作随机变量的正态分布的工具.
1>>> 2>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14]) 3>>> temperature_feb 4NormalDist(mu=6.0, sigma=6.356099432828281) 5 6>>> temperature_feb.cdf(3) # Chance of being under 3 degrees 70.3184678262814532 8>>> # Relative chance of being 7 degrees versus 10 degrees 9>>> temperature_feb.pdf(7) / temperature_feb.pdf(10) 101.2039930378537762 11 12>>> el_nino = NormalDist(4, 2.5) 13>>> temperature_feb += el_nino # Add in a climate effect 14>>> temperature_feb 15NormalDist(mu=10.0, sigma=6.830080526611674) 16 17>>> temperature_feb * (9/5) + 32 # Convert to Fahrenheit 18NormalDist(mu=50.0, sigma=12.294144947901014) 19>>> temperature_feb.samples(3) # Generate random samples 20[7.672102882379219, 12.000027119750287, 4.647488369766392]
该tarfile模块现在默认为新档案的现代pax(POSIX.1-2001)格式,而不是之前的GNU特定格式。这通过标准化和可扩展格式的一致编码(UTF-8)提高了跨平台的可移植性,并提供了其他一些好处。
当提供没有尾随新行的输入时,tokenize模块现在隐式地发出NEWLINE令牌。此行为现在与C tokenizer在内部执行的操作相匹配。
添加的方法selection_from(), selection_present(), selection_range()和 selection_to() 在tkinter.Spinbox类。
moveto() 在tkinter.Canvas课堂上添加了方法。
CLOCK_UPTIME_RAW为macOS 10.12 添加了新时钟。
新函数is_normalized()
可用于验证字符串是否处于特定的正常形式。
添加addModuleCleanup()并 addClassCleanup()进行unittest以支持setUpModule()和的 清理setUpClass()。
venv现在,Activate.ps1在PowerShell Core 6.1下,所有平台上都包含一个用于激活虚拟环境的脚本。
作为对DTD和外部实体检索的缓解,默认情况下, xml.dom.minidom和xml.sax模块不再处理外部实体。
macOS
和Linux
-close_fds为false;
未设置preexec_fn,pass_fds,cwd和start_new_session参数;
该可执行文件路径中包含一个目录。
-shutil.copyfile(),shutil.copy(),shutil.copy2(), shutil.copytree()并shutil.move()使用特定于平台的“快速复制”在Linux,MacOS的和Solaris,以更有效地复制文件系统调用。“快速复制”意味着复制操作发生在内核中,避免在Python中使用用户空间缓冲区,如“ outfd.write(infd.read())”。在Windows上shutil.copyfile()使用更大的默认缓冲区大小(1 MiB而不是16 KiB),并使用memoryview()基于a 的变体 - shutil.copyfileobj()。在同一分区中复制512 MiB文件的速度在Linux上约为+ 26%,在macOS上为+ 50%,在Windows上为+ 40%。此外,消耗的CPU周期更少。请参阅与平台相关的高效复制操作部分。
Modules/Setup.dist
和 Modules/Setup
已被删除。以前,在更新CPython源代码树时,必须手动将Modules/Setup.dist(在源代码树内)复制到 Modules/Setup(在构建树内)以反映上游的任何更改。这对包装商来说是一个小小的好处,代价是CPython开发后开发人员经常烦恼,因为忘记复制文件可能会导致构建失败。
PyLong_AsLong()
函数和参数解析函数(如 PyArg_ParseTuple()整数转换格式单位)'i' 现在将使用__index__()
特殊方法而不是( int__()如果可用)。将使用_int_()方法但没有 _index_()方法(如Decimal和 Fraction)
为对象发出弃用警告。 PyNumber_Check()
现在将返回 1实现的对象__index()。
getchildren()
,getiterator()
在ElementTree
模块现在发出 DeprecationWarning
来代替PendingDeprecationWarning
。它们将在Python 3.9中删除。
concurrent.futures.ThreadPoolExecutorto
的实例的对象已 asyncio.loop.set_default_executor()
被弃用,并且将在Python 3.9中被禁止。
getitem()
方法xml.dom.pulldom.DOMEventStream
, wsgiref.util.FileWrapper
并fileinput.FileInput已被弃用。
这些方法的实现忽略了它们的索引参数,而是返回下一个项目。
typing.NamedTuple
已否决了,_field_types
赞成的属性__annotations
__具有相同信息的属性。
ast类Num,Str,Bytes,NameConstant
和 Ellipsis
被标记是过时的,并将在未来的Python版本中删除。Constant应该用来代替。
lgettext()
,ldgettext()
, lngettext()和ldngettext()。它们返回编码的字节,如果翻译的字符串存在编码问题,则可能会出现意外的与Unicode相关的异常。在Python 3中使用返回Unicode字符串的替代方法要好得多。这些功能已经被打破了很长时间。
bind_textdomain_codeset()
,方法 output_charset()
和 set_output_charset()
,以及代码集 的功能参数translation()
和install()
也不赞成使用,因为它们仅用于为l*gettext()功能。
-该isAlive()
方法threading.Thread
已被弃用。
许多带有整数参数的内置函数和扩展函数现在将为Decimals,Fractions和任何其他对象发出弃用警告, 这些对象只能在丢失的情况下转换为整数(例如,具有int__() 方法但没有__index()方法)。在将来的版本中,它们将是错误的。
macpath
已删除在Python 3.7
中弃用的模块。
该函数platform.popen()
已被删除,自Python 3.3以来已被弃用:os.popen()改为使用。
m venvpyvenv
parse_qs,parse_qsl
和escape
从除去cgi 模块。它们已从Python 3.2或更早版本弃用。
filemode
功能已从tarfile
模块中删除。自Python 3.3以来,它没有记录和弃用。
该XMLParser
构造不再接受HTML
参数。它从未产生过影响,在Python 3.4中已被弃用。所有其他参数现在都是仅关键字。
unicode_internal
编解码器被删除。
本节列出了先前描述的更改以及可能需要更改代码的其他错误修正。
## Python行为的变化
SyntaxWarning
何时身份检查 与某些类型的文字(例如字符串,整数)一起使用。这些通常可以在CPython
中偶然使用,但不受语言规范的保证。警告建议用户使用相等测试。
platform.popen()
已被删除,自Python 3.3以来已被弃用:os.popen()改为使用。
statistics.mode()
给定多模态数据时,该函数不再引发异常。相反,它返回输入数据中遇到的第一个模式。
该类的selection()
方法 tkinter.ttk.Treeview
不再需要参数。在Python 3.6中不推荐使用带有参数来更改选择。使用专门的方法,如selection_set()
更改选择。
doctype()
子类中定义的方法, XMLParser
并且将导致发出a RuntimeWarning而不是a DeprecationWarning
。doctype()
在目标上定义用于处理XML doctype声明的方法。
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
, shutil.copytree()
并shutil.move()
使用特定于平台的“快速复制”的系统调用
shutil.copyfile()
Windows上的默认缓冲区大小从16 KiB更改为1 MiB。
PyGC_Head
结构完全改变了。触及struct
成员的所有代码都应该被重写。
PyInterpreterState
结构已被移入“内部”头文件(特别是Include / internal / pycore_pystate.h)。opaque PyInterpreterState
仍然可用作公共API(和稳定的ABI)的一部分。文档表明struct的字段都不公开,所以我们希望没有人使用它们。但是,如果您确实依赖于一个或多个私有字段而没有其他选择,那么请打开一个BPO问题。我们将努力帮助您进行调整(可能包括向公共API添加访问器功能)。
asyncio.create_task()
或create_task()事件循环的方法,或者通过调用set_name()
任务对象的方法。任务名称在repr()输出中可见,asyncio.Task
也可以使用该get_name()
方法检索。
mmap.flush()
方法现在返回None成功并在所有平台下引发错误异常。以前,它的行为是平台依赖的:成功时返回非零值; 在Windows下错误返回零。成功返回零值; 在Unix下出现异常错误。
math.factorial()
不再接受非int类的参数。
xml.dom.minidom和xml.sax
模块默认不再处理外部实体。
expanduser()
在Windows上现在更喜欢 USERPROFILE 环境变量,不使用 HOME,通常不为常规用户帐户设置。
使用#在分析或建筑价值的形式变体(例如 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()
。
例:
1static foo_struct * 2foo_new(PyObject *type) { 3 foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); 4 if (foo == NULL) 5 return NULL; 6#if PY_VERSION_HEX < 0x03080000 7 // Workaround for Python issue 35810; no longer necessary in Python 3.8 8 PY_INCREF(type) 9#endif 10 return foo; 11}
确保 tp_dealloc
堆分配类型的所有自定义函数都减少了类型的引用计数。
例:
1 static void 2foo_dealloc(foo_struct *instance) { 3 PyObject *type = Py_TYPE(instance); 4 PyObject_GC_Del(instance); 5#if PY_VERSION_HEX >= 0x03080000 6 // This was not needed before Python 3.8 (Python issue 35810) 7 Py_DECREF(type); 8#endif 9}
通过移动将块堆栈展开到编译器中的逻辑,简化了解释器循环。编译器现在发出显式指令,用于调整值堆栈并调用清理代码break
,continue
和 return
。
删除操作码BREAK_LOOP,CONTINUE_LOOP
, SETUP_LOOP和SETUP_EXCEPT
。增加了新的操作码ROT_FOUR,BEGIN_FINALLY,CALL_FINALLY
和 POP_FINALLY。改变了
END_FINALLY和
WITH_CLEANUP_START。 添加了新的操作码,
END_ASYNC_FOR`用于处理在等待循环中的下一个项目时引发的异常。
领取专属 10元无门槛券
私享最新 技术干货