Python 3.8 新特性全面解读

发表于:2019-4-02 10:35

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:佚名    来源:开源中国

   单元测试
  添加addModuleCleanup()并 addClassCleanup()进行unittest以支持setUpModule()和的 清理setUpClass()。
  VENV
  venv现在,Activate.ps1在PowerShell Core 6.1下,所有平台上都包含一个用于激活虚拟环境的脚本。
  XML
  作为对DTD和外部实体检索的缓解,默认情况下, xml.dom.minidom和xml.sax模块不再处理外部实体。
  优化
  subprocess现在,模块可以os.posix_spawn()在某些情况下使用该功能以获得更好的性能。目前,如果满足所有这些条件,它仅用于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周期更少。请参阅与平台相关的高效复制操作部分。
  shutil.copytree()使用os.scandir()函数和依赖它的所有复制函数使用缓存os.stat()值。复制具有8000个文件的目录的速度在Linux上约为+ 9%,在Windows上为+ 20%,在Windows SMB共享上为+ 30%。此外,os.stat() 系统调用的数量减少了38%,使shutil.copytree()网络文件系统的速度更快。
  -pickle模块中的默认协议现在是协议4,首先在Python 3.4中引入。与Python 3.0以来提供的Protocol 3相比,它提供了更好的性能和更小的尺寸。
  删除了一个Py_ssize_t成员PyGC_Head。所有GC跟踪对象(例如元组,列表,字典)的大小减少了4或8个字节。
  uuid.UUID现在用于slots__减少其内存占用。 -性能提升operator.itemgetter()了33%。优化参数处理并为单个非负整数索引的常见情况添加快速路径到元组(这是标准库中的典型用例)。 -加速字段查找collections.namedtuple()。它们现在的速度提高了两倍以上,使它们成为Python中最快的实例变量查找形式。 -list如果输入iterable具有已知长度(输入实现__len),则构造函数不会全局定位内部项缓冲区。这使得创建的列表平均减少12%。(由Raymond Hettinger和Pablo Galindo在bpo-33234中提供。)
  -将类变量写入的速度加倍。更新非dunder属性时,会有不必要的更新插槽调用。(由Stefan Behnel,Pablo Galindo Salgado,Raymond Hettinger,Neil Schemenauer和Serhiy Storchaka供稿于bpo-36012。)
  -减少转换传递给许多内置函数和方法的参数的开销。加快调用一些简单的内置函数和方法,最多可达20-50%。(由Serhiy Storchaka在bpo-23867, bpo-35582和bpo-36127供稿。)
  构建和C API更改
  这些PyByteArray_Init()和PyByteArray_Fini()功能已被删除。他们没有做任何事情,因为Python 2.7.4和Python 3.2.0被排除在有限的API(稳定的ABI)之外,并且没有记录。
  结果PyExceptionClass_Name()现在是类型 而不是。const char *char *
  二元性Modules/Setup.dist和 Modules/Setup已被删除。以前,在更新CPython源代码树时,必须手动将Modules/Setup.dist(在源代码树内)复制到 Modules/Setup(在构建树内)以反映上游的任何更改。这对包装商来说是一个小小的好处,代价是CPython开发后开发人员经常烦恼,因为忘记复制文件可能会导致构建失败。
  现在构建系统总是从Modules/Setup源树内部读取。鼓励想要自定义该文件的人将其更改保存在CPython的git fork中或作为补丁文件,就像它们对源树的任何其他更改一样。
  将Python数转换为C整数的 PyLong_AsLong()函数和参数解析函数(如 PyArg_ParseTuple()整数转换格式单位)'i' 现在将使用__index__()特殊方法而不是( int__()如果可用)。将使用_int_()方法但没有 _index_()方法(如Decimal和 Fraction)为对象发出弃用警告。 PyNumber_Check()现在将返回 1实现的对象__index()。
  堆分配的类型对象现在将增加它们PyObject_Init()(和它的并行宏PyObject_INIT)中的引用计数而不是in PyType_GenericAlloc()。可能需要调整修改实例分配或释放的类型。
  不支持
  不建议使用的方法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应该用来代替。
  下面的函数和方法弃用在gettext 模块: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()方法)。在将来的版本中,它们将是错误的。
  API和功能删除
  从`Python 3.8`中删除了以下功能和API:
  macpath已删除在Python 3.7中弃用的模块。
  该函数platform.popen()已被删除,自Python 3.3以来已被弃用:os.popen()改为使用。
  该pyvenv脚本已被删除, 以帮助消除关于 脚本绑定的Python解释器的混淆。python3.8 -m venvpyvenv
  parse_qs,parse_qsl和escape从除去cgi 模块。它们已从Python 3.2或更早版本弃用。
  filemode功能已从tarfile模块中删除。自Python 3.3以来,它没有记录和弃用。
  该XMLParser构造不再接受HTML参数。它从未产生过影响,在Python 3.4中已被弃用。所有其他参数现在都是仅关键字。
  删除了doctype()方法XMLParser。
  unicode_internal编解码器被删除。
  移植
  本节列出了先前描述的更改以及可能需要更改代码的其他错误修正。
  ## Python行为的变化
  屈服表达式(both yield和子句)现在在理解和生成器表达式中是不允许的(除了最左边的子句中的可迭代表达式)
  编译器现在生成一个SyntaxWarning何时身份检查 与某些类型的文字(例如字符串,整数)一起使用。这些通常可以在CPython中偶然使用,但不受语言规范的保证。警告建议用户使用相等测试。
  Python API的变化
  该函数platform.popen()已被删除,自Python 3.3以来已被弃用:os.popen()改为使用。
  statistics.mode()给定多模态数据时,该函数不再引发异常。相反,它返回输入数据中遇到的第一个模式。
  该类的selection()方法 tkinter.ttk.Treeview不再需要参数。在Python 3.6中不推荐使用带有参数来更改选择。使用专门的方法,如selection_set()更改选择。
  writexml(),toxml()并且toprettyxml()所述的方法 xml.dom.minidom模块,和xml.etree现在保存由用户指定的属性顺序。(
  -dbm.dumb使用flags打开的数据库'r'现在是只读的。 dbm.dumb.open()带有标志'r','w'如果不存在则不再创建数据库。
  将不再调用doctype()子类中定义的方法, XMLParser并且将导致发出a RuntimeWarning而不是a DeprecationWarning。doctype()在目标上定义用于处理XML doctype声明的方法。
  一个RuntimeError是现在时引发自定义的元类不提供classcell__传入的名称空间项 type.__new。A DeprecationWarning是在Python 3.6-3.7中发出的。
  在cProfile.Profile类现在可以作为一个上下文管理器。
  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任务现在可以命名,或者通过将name关键字参数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模块默认不再处理外部实体。
  从只读dbm数据库(dbm.dumb, dbm.gnu或dbm.ndbm)中删除密钥会引发error(dbm.dumb.error, dbm.gnu.error或dbm.ndbm.error)而不是KeyError。
  expanduser()在Windows上现在更喜欢 USERPROFILE 环境变量,不使用 HOME,通常不为常规用户帐户设置。
  使用#在分析或建筑价值的形式变体(例如 PyArg_ParseTuple(),Py_BuildValue(),PyObject_CallFunction()没有等)PY_SSIZE_T_CLEAN定义提出了DeprecationWarning现在。它将在3.10或4.0中删除。阅读解析参数并为细节构建值。(由Inada Naoki在bpo-36381供稿。)
  C API的变化
  -堆分配类型的实例(例如用其创建的实例 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}
  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。 添加了新的操作码,END_ASYNC_FOR`用于处理在等待循环中的下一个项目时引发的异常。

     上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号