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:
新的函式庫模組:
新的內建功能:
PEP 553, the new
breakpoint()function.
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.
標準函式庫中的顯著改進
The
asynciomodule has received new features, significant usability and performance improvements.The
timemodule gained support for functions with nanosecond resolution.
CPython 實作改進:
Avoiding the use of ASCII as a default text encoding:
PEP 552, deterministic .pycs
PEP 565, improved
DeprecationWarninghandling
C API 改進:
PEP 539, new C API for thread-local storage
Documentation improvements:
PEP 545, Python documentation translations
New documentation translations: Japanese, French, and Korean.
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 toDeprecationWarningorFutureWarning.
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.,