Python 3.7 有什麼新功能

編輯者:

Elvis Pranskevichus <elvis@magic.io>

本文介紹了 Python 3.7 與 3.6 相比多了哪些新功能。Python 3.7 已於 2018 年 6 月 27 日發布。有關完整詳細資訊,請參閱 changelog

發布重點摘要

新增語法特性:

  • PEP 563, postponed evaluation of type annotations.

Backwards incompatible syntax changes:

新的函式庫模組:

新的內建功能:

Python 資料模型改進:

  • PEP 562, customization of access to module attributes.

  • PEP 560, core support for typing module and generic types.

  • the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec.

標準函式庫中的顯著改進

CPython 實作改進:

C API 改進:

  • PEP 539, new C API for thread-local storage

Documentation improvements:

This release features notable performance improvements in many areas. The 最佳化 section lists them in detail.

For a list of changes that may affect compatibility with previous Python releases please refer to the 移植至 Python 3.7 section.

新增功能

PEP 563:延後評估註釋

The advent of type hints in Python uncovered two glaring usability issues with the functionality of annotations added in PEP 3107 and refined further in PEP 526:

  • annotations could only use names which were already available in the current scope, in other words they didn't support forward references of any kind; and

  • annotating source code had adverse effects on startup time of Python programs.

Both of these issues are fixed by postponing the evaluation of annotations. Instead of compiling code which executes expressions in annotations at their definition time, the compiler stores the annotation in a string form equivalent to the AST of the expression in question. If needed, annotations can be resolved at runtime using typing.get_type_hints(). In the common case where this is not required, the annotations are cheaper to store (since short strings are interned by the interpreter) and make startup time faster.

Usability-wise, annotations now support forward references, making the following syntax valid:

class C:
    @classmethod
    def from_string(cls, source: str) -> C:
        ...

    def validate_b(self, obj: B) -> bool:
        ...

class B:
    ...

Since this change breaks compatibility, the new behavior needs to be enabled on a per-module basis in Python 3.7 using a __future__ import:

from __future__ import annotations

這將在 Python 3.10 中成為預設值。

也參考

PEP 563 -- Postponed evaluation of annotations

PEP written and implemented by Łukasz Langa.

PEP 538: Legacy C Locale Coercion

An ongoing challenge within the Python 3 series has been determining a sensible default strategy for handling the "7-bit ASCII" text encoding assumption currently implied by the use of the default C or POSIX locale on non-Windows platforms.

PEP 538 updates the default interpreter command line interface to automatically coerce that locale to an available UTF-8 based locale as described in the documentation of the new PYTHONCOERCECLOCALE environment variable. Automatically setting LC_CTYPE this way means that both the core interpreter and locale-aware C extensions (such as readline) will assume the use of UTF-8 as the default text encoding, rather than ASCII.

The platform support definition in PEP 11 has also been updated to limit full text handling support to suitably configured non-ASCII based locales.

As part of this change, the default error handler for stdin and stdout is now surrogateescape (rather than strict) when using any of the defined coercion target locales (currently C.UTF-8, C.utf8, and UTF-8). The default error handler for stderr continues to be backslashreplace, regardless of locale.

Locale coercion is silent by default, but to assist in debugging potentially locale related integration problems, explicit warnings (emitted directly on stderr) can be requested by setting PYTHONCOERCECLOCALE=warn. This setting will also cause the Python runtime to emit a warning if the legacy C locale remains active when the core interpreter is initialized.

While PEP 538's locale coercion has the benefit of also affecting extension modules (such as GNU readline), as well as child processes (including those running non-Python applications and older versions of Python), it has the downside of requiring that a suitable target locale be present on the running system. To better handle the case where no suitable target locale is available (as occurs on RHEL/CentOS 7, for example), Python 3.7 also implements PEP 540: Forced UTF-8 Runtime Mode.

也參考

PEP 538 -- Coercing the legacy C locale to a UTF-8 based locale

由 Nick Coghlan 撰寫 PEP 與實作。

PEP 540: Forced UTF-8 Runtime Mode

The new -X utf8 command line option and PYTHONUTF8 environment variable can be used to enable the Python UTF-8 Mode.

When in UTF-8 mode, CPython ignores the locale settings, and uses the UTF-8 encoding by default. The error handlers for sys.stdin and sys.stdout streams are set to surrogateescape.

The forced UTF-8 mode can be used to change the text handling behavior in an embedded Python interpreter without changing the locale settings of an embedding application.

While PEP 540's UTF-8 mode has the benefit of working regardless of which locales are available on the running system, it has the downside of having no effect on extension modules (such as GNU readline), child processes running non-Python applications, and child processes running older versions of Python. To reduce the risk of corrupting text data when communicating with such components, Python 3.7 also implements PEP 540: Forced UTF-8 Runtime Mode).

The UTF-8 mode is enabled by default when the locale is C or POSIX, and the PEP 538 locale coercion feature fails to change it to a UTF-8 based alternative (whether that failure is due to PYTHONCOERCECLOCALE=0 being set, LC_ALL being set, or the lack of a suitable target locale).

也參考

PEP 540 -- 新增 UTF-8 模式

由 Victor Stinner 撰寫 PEP 與實作

PEP 553:內建的 breakpoint()

Python 3.7 includes the new built-in breakpoint() function as an easy and consistent way to enter the Python debugger.

Built-in breakpoint() calls sys.breakpointhook(). By default, the latter imports pdb and then calls pdb.set_trace(), but by binding sys.breakpointhook() to the function of your choosing, breakpoint() can enter any debugger. Additionally, the environment variable PYTHONBREAKPOINT can be set to the callable of your debugger of choice. Set PYTHONBREAKPOINT=0 to completely disable built-in breakpoint().

也參考

PEP 553 -- 內建的 breakpoint()

由 Barry Warsaw 撰寫 PEP 與實作

PEP 539: New C API for Thread-Local Storage

While Python provides a C API for thread-local storage support; the existing Thread Local Storage (TLS) API has used int to represent TLS keys across all platforms. This has not generally been a problem for officially support platforms, but that is neither POSIX-compliant, nor portable in any practical sense.

PEP 539 changes this by providing a new Thread Specific Storage (TSS) API to CPython which supersedes use of the existing TLS API within the CPython interpreter, while deprecating the existing API. The TSS API uses a new type Py_tss_t instead of int to represent TSS keys--an opaque type the definition of which may depend on the underlying TLS implementation. Therefore, this will allow to build CPython on platforms where the native TLS key is defined in a way that cannot be safely cast to int.

Note that on platforms where the native TLS key is defined in a way that cannot be safely cast to int, all functions of the existing TLS API will be no-op and immediately return failure. This indicates clearly that the old API is not supported on platforms where it cannot be used reliably, and that no effort will be made to add such support.

也參考

PEP 539 -- A New C-API for Thread-Local Storage in CPython

PEP 由 Erik M. Bray 撰寫;由 Masayuki Yamamoto 實作。

PEP 562: Customization of Access to Module Attributes

Python 3.7 allows defining __getattr__() on modules and will call it whenever a module attribute is otherwise not found. Defining __dir__() on modules is now also allowed.

A typical example of where this may be useful is module attribute deprecation and lazy loading.

也參考

PEP 562 -- __getattr____dir__ 模組

由 Ivan Levkivskyi 撰寫 PEP 與實作

PEP 564: New Time Functions With Nanosecond Resolution

The resolution of clocks in modern systems can exceed the limited precision of a floating-point number returned by the time.time() function and its variants. To avoid loss of precision, PEP 564 adds six new "nanosecond" variants of the existing timer functions to the time module:

The new functions return the number of nanoseconds as an integer value.

Measurements show that on Linux and Windows the resolution of time.time_ns() is approximately 3 times better than that of time.time().

也參考

PEP 564 -- Add new time functions with nanosecond resolution

由 Victor Stinner 撰寫 PEP 與實作

PEP 565:在 __main__ 中顯示 DeprecationWarning

The default handling of DeprecationWarning has been changed such that these warnings are once more shown by default, but only when the code triggering them is running directly in the __main__ module. As a result, developers of single file scripts and those using Python interactively should once again start seeing deprecation warnings for the APIs they use, but deprecation warnings triggered by imported application, library and framework modules will continue to be hidden by default.

As a result of this change, the standard library now allows developers to choose between three different deprecation warning behaviours:

  • FutureWarning: always displayed by default, recommended for warnings intended to be seen by application end users (e.g. for deprecated application configuration settings).

  • DeprecationWarning: displayed by default only in __main__ and when running tests, recommended for warnings intended to be seen by other Python developers where a version upgrade may result in changed behaviour or an error.

  • PendingDeprecationWarning: displayed by default only when running tests, intended for cases where a future version upgrade will change the warning category to DeprecationWarning or FutureWarning.

Previously both DeprecationWarning and PendingDeprecationWarning were only visible when running tests, which meant that developers primarily writing single file scripts or using Python interactively could be surprised by breaking changes in the APIs they used.

也參考

PEP 565 -- 在 __main__ 中顯示 DeprecationWarning

由 Nick Coghlan 撰寫 PEP 與實作

PEP 560:對 typing 模組與泛用型別的核心支援

Initially PEP 484 was designed in such way that it would not introduce any changes to the core CPython interpreter. Now type hints and the typing module are extensively used by the community, so this restriction is removed. The PEP introduces two special methods __class_getitem__() and __mro_entries__(), these methods are now used by most classes and special constructs in typing. As a result, the speed of various operations with types increased up to 7 times, the generic types can be used without metaclass conflicts, and several long standing bugs in typing module are fixed.

也參考

PEP 560 -- 對 typing 模組與泛用型別的核心支援

由 Ivan Levkivskyi 撰寫 PEP 與實作

PEP 552:基於雜湊值的 .pyc 檔案

Python has traditionally checked the up-to-dateness of bytecode cache files (i.e.,