Python3.6新特性

本文解释了Python 3.6中的新功能,与3.5相比。Python 3.6于2016年12月23日发布。有关完整的详细信息,请参阅更新日志。

Summary – Release highlights(摘要)

新特性

  • PEP 498, formatted string literals.
    (格式化的字符串文字。)
  • PEP 515, underscores in numeric literals.
    (以数字文字表示。)
  • PEP 526, syntax for variable annotations.
    (变量注释的语法。)
  • PEP 525, asynchronous generators.
    (异步发生器。)
  • PEP 530: asynchronous comprehensions.
    (异步理解。)

CPython实现改进

CPython implementation improvements:

  • The dict(字典,python的基本类型) type has been reimplemented to use a more compact representation based on a proposal by Raymond Hettinger and similar to the PyPy dict implementation(PyPy dict实现). This resulted in dictionaries using 20% to 25% less memory when compared to Python 3.5.
    (该字典类型已重新实现使用更紧凑的表示 基于由雷蒙德·赫廷格的建议 和类似PyPy字典实现。与Python 3.5相比,这使得字典的内存减少了20%到25%。)
  • Customization of class creation has been simplified with the new protocol.
    (通过新协议简化了类创建的定制 。)
  • The class attribute definition order is now preserved.
    (类属性定义顺序 现在被保留。)
  • The order of elements in kwargs now corresponds to the order in which keyword arguments were passed to the function.
    kwargs中的元素顺序现在对应于传递给函数的关键字参数的顺序。)
    DTrace and SystemTap probing support has been added.
    (添加了DTrace和SystemTap探测支持。)
  • The new PYTHONMALLOC environment variable can now be used to debug the interpreter memory allocation and access errors.
    (现在可以使用新的PYTHONMALLOC环境变量来调试解释器内存分配和访问错误。)

标准库的重大改进:

Significant improvements in the standard library

  • The asyncio module has received new features, significant usability and performance improvements, and a fair amount of bug fixes. Starting with Python 3.6 the asyncio module is no longer provisional and its API is considered stable.
    (该asyncio模块已经获得了新功能,显着的可用性和性能改进,以及大量的错误修复。从Python 3.6开始,该asyncio模块不再是临时的,它的API被认为是稳定的。)
  • A new file system path protocol has been implemented to support path-like objects. All standard library functions operating on paths have been updated to work with the new protocol.
  • (已经实现了一种新的文件系统路径协议来支持类似路径的对象。所有在路径上运行的标准库函数都已更新,以配合新协议)
  • The datetime module has gained support for Local Time Disambiguation.
    (该datetime模块获得了当地时间消歧的支持 。)
    The typing module received a number of improvements.
    (typing模块接受了一些 改进。)
  • The tracemalloc module has been significantly reworked and is now used to provide better output for ResourceWarning as well as provide better diagnostics for memory allocation errors. See the PYTHONMALLOC section for more information.
    (该tracemalloc模块已经大大改造,现在用于提供更好的输出ResourceWarning以及为内存分配错误提供更好的诊断。有关详细信息,请参阅PYTHONMALLOC部分。)

安全改进

  • The new secrets module has been added to simplify the generation of cryptographically strong pseudo-random numbers suitable for managing secrets such as account authentication, tokens, and similar.
  • On Linux, os.urandom() now blocks until the system urandom entropy pool is initialized to increase the security. See the PEP 524 for the rationale.
  • The hashlib and ssl modules now support OpenSSL 1.1.0.
  • The default settings and feature set of the ssl module have been improved.
  • The hashlib module received support for the BLAKE2, SHA-3 and SHAKE hash algorithms and the scrypt() key derivation function.
    (该hashlib模块支持BLAKE2,SHA-3和SHAKE哈希算法以及scrypt()密钥导出功能。)

Windows improvements

  • PEP 528 and PEP 529, Windows filesystem and console encoding changed to UTF-8.
    (Windows文件系统和控制台编码更改为UTF-8)
  • The py.exe launcher, when used interactively, no longer prefers Python 2 over Python 3 when the user doesn’t specify a version (via command line arguments or a config file). Handling of shebang lines remains unchanged - “python” refers to Python 2 in that case.
  • (py.exe当用户没有指定版本(通过命令行参数或配置文件)时,启动器在交互式使用时不再使用Python 2,而是使用Python 3。shebang行的处理保持不变 - “python”在这种情况下是指Python 2。)
  • python.exe and pythonw.exe have been marked as long-path aware, which means that the 260 character path limit may no longer apply. See removing the MAX_PATH limitation for details.
    (python.exe和pythonw.exe已被标记为长光程知道,这意味着260个字符的- 路径限制可能不再适用。有关详细信息,请参阅删除MAX_PATH限制。)
  • A ._pth file can be added to force isolated mode and fully specify all search paths to avoid registry and environment lookup. See the documentation for more information.
    (一个._pth文件可以被添加到强制隔离模式和完全指定所有的搜索路径,以避免注册表和环境查找。有关详细信息,请参阅 文档。)
  • A python36.zip file now works as a landmark to infer PYTHONHOME. See the documentation for more information.
    (一个python36.zip文件现在作为一个里程碑推断 PYTHONHOME。有关详细信息,请参阅文档。)

New Features(新功能)

Formatted string literals(string的格式化)

Formatted string literals are prefixed with 'f' and are similar to the format strings accepted by str.format(). They contain replacement fields surrounded by curly braces. The replacement fields are expressions, which are evaluated at run time, and then formatted using the format() protocol:
(字符串的格式化类似于字符串f的str.format()格式化。它们包含被大括号包围的替换字段。替换字段是在运行时如何格式的表达式,然后使用format()协议进行格式化 )

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"  # nested fields
'result:      12.35'

变量注释的语法

Syntax for variable annotations

introduced the standard for type annotations of function parameters, a.k.a. type hints. This PEP adds syntax to Python for annotating the types of variables including class variables and instance variables:
(引入了功能参数类型注释的标准,也称为类型提示。这个PEP添加了Python的语法来注释变量的类型,包括类变量和实例变量:)

primes: List[int] = []

captain: str  # Note: no initial value!

class Starship:
    stats: Dict[str, int] = {}

  Just as for function annotations, the Python interpreter does not attach any particular meaning to variable annotations and only stores them in the annotations attribute of a class or module.

   In contrast to variable declarations in statically typed languages, the goal of annotation syntax is to provide an easy way to specify structured type metadata for third party tools and libraries via the abstract syntax tree and the annotations attribute.

(  就像函数注释一样,Python解释器对变量注释没有附加任何特定的含义,只将它们存储在__annotations__类或模块的 属性中。

  与静态类型语言中的变量声明相反,注释语法的目的是提供一种通过抽象语法树和__annotations__属性为第三方工具和库指定结构化类型元数据的简单方法。)

数字的增强

Underscores in Numeric Literals

   adds the ability to use underscores in numeric literals for improved readability. For example:
(增加了在数字文字中使用下划线的能力,以提高可读性。例如)

>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295

Single underscores are allowed between digits and after any base specifier. Leading, trailing, or multiple underscores in a row are not allowed.

The string formatting language also now has support for the '_' option to signal the use of an underscore for a thousands separator for floating point presentation types and for integer presentation type 'd'. For integer presentation types 'b', 'o', 'x', and 'X', underscores will be inserted every 4 digits:

(  允许在数字之间和任何基本说明符之后使用单个下划线。不允许一行中的前导,尾随或多个下划线。

  该字符串格式化语言现在也拥有了支持'_'信号为千位分隔符使用下划线的浮点呈现类型和整数呈现类型选项'd'。对于整数呈现类型'b', 'o','x',和'X',下划线将被插入每4个位数:)

>>> '{:_}'.format(1000000)
'1_000_000'
>>> '{:_x}'.format(0xFFFFFFFF)
'ffff_ffff'

异步发生器

  引入了对本地协同程序的支持和async/await 或Python 3.5语法。Python 3.5实现的一个显着的限制是不可能使用await和yield在同一个功能体中。在Python 3.6中,这个限制被解除了,可以定义异步发生器:

async def ticker(delay, to):
    """Yield numbers from 0 to *to* every *delay* seconds."""
    for i in range(to):
        yield i
        await asyncio.sleep(delay)

新语法允许更快更简洁的代码。

异步支持

 adds support for using async for in list, set, dict comprehensions and generator expressions:
  (增加了在列表,集合,字母推导和生成器表达式中的使用支持:async for)

result = [i async for i in aiter() if i % 2]

  Additionally, await expressions are supported in all kinds of comprehensions:
  (另外,await表达式支持各种理解:)

result = [await fun() for fun in funcs if await condition()]

定制类创建的简化

  It is now possible to customize subclass creation without using a metaclass. The new init_subclass classmethod will be called on the base class whenever a new subclass is created:

  (现在可以定制子类创建而不使用元类。新__init_subclass__类方法将在基类每当创建一个新的子类被称为:)

class PluginBase:
    subclasses = []

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.subclasses.append(cls)

class Plugin1(PluginBase):
    pass

class Plugin2(PluginBase):
    pass

  In order to allow zero-argument super() calls to work correctly from init_subclass() implementations, custom metaclasses must ensure that the new classcell namespace entry is propagated to type.new (as described in Creating the class object).
  (为了允许零参数super()调用从__init_subclass__()实现中正常工作 ,自定义元类必须确保新的__classcell__命名空间条目被传播到 type.new(如创建类对象中所述)。)

描述符协议增强

  extends the descriptor protocol to include the new optional set_name() method. Whenever a new class is defined, the new method will be called on all descriptors included in the definition, providing them with a reference to the class being defined and the name given to the descriptor within the class namespace. In other words, instances of descriptors can now know the attribute name of the descriptor in the owner class:

  (扩展描述符协议以包括新的可选 set_name()方法。每当定义一个新类时,将调用定义中包含的所有描述符的新方法,为它们提供对定义的类的引用,以及类名称空间中给描述符的名称。换句话说,描述符的实例现在可以知道所有者类中的描述符的属性名称:)

class IntField:
    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError(f'expecting integer in {self.name}')
        instance.__dict__[self.name] = value

    # this is the new initializer:
    def __set_name__(self, owner, name):
        self.name = name

class Model:
    int_field = IntField()

文件系统路径协议的增加

Adding a file system path protocol

File system paths have historically been represented as str or bytes objects. This has led to people who write code which operate on file system paths to assume that such objects are only one of those two types (an int representing a file descriptor does not count as that is not a file path). Unfortunately that assumption prevents alternative object representations of file system paths like pathlib from working with pre-existing code, including Python’s standard library.

(文件系统路径历来被表示为str 或bytes对象。这导致编写在文件系统路径上操作的代码的人们认为这样的对象只是这两种类型之一(int表示一个文件描述符不被视为不是文件路径)。不幸的是,这种假设阻止了文件系统路径的替代对象表示,例如pathlib使用预先存在的代码,包括Python的标准库。)

To fix this situation, a new interface represented by os.PathLike has been defined. By implementing the fspath() method, an object signals that it represents a path. An object can then provide a low-level representation of a file system path as a str or bytes object. This means an object is considered path-like if it implements os.PathLike or is a str or bytes object which represents a file system path. Code can use os.fspath(), os.fsdecode(), or os.fsencode() to explicitly get a str and/or bytes representation of a path-like object.
(为了解决这种情况,os.PathLike已经定义了一个新的界面 。通过实现该 fspath()方法,一个对象表示它表示路径。然后,对象可以提供作为str或 bytes对象的文件系统路径的低级表示。这意味着一个对象被认为是 路径,如果它实现 os.PathLike或是一个str或bytes表示文件系统路径的对象。代码可以使用os.fspath(), os.fsdecode()或os.fsencode()显式地获得一个 str和/或bytes一个类似路径的对象的表示。)

The built-in open() function has been updated to accept os.PathLike objects, as have all relevant functions in the os and os.path modules, and most other functions and classes in the standard library. The os.DirEntry class and relevant classes in pathlib have also been updated to implement os.PathLike.

(内置open()函数已被更新为接受 os.PathLike对象,os以及os.path模块中的所有相关功能 以及标准库中的大多数其他功能和类。本os.DirEntry类和相关类pathlib也进行了更新来实现os.PathLike。)

The hope is that updating the fundamental functions for operating on file system paths will lead to third-party code to implicitly support all path-like objects without any code changes, or at least very minimal ones (e.g. calling os.fspath() at the beginning of code before operating on a path-like object).

  (希望更新文件系统路径上运行的基本功能将导致第三方代码隐含地支持所有类似路径的对象,而无需任何代码更改,或至少非常小的os.fspath()代码(例如在操作开始时调用 代码)在路径样的对象上)。)

以下是一些示例,说明如何pathlib.Path使用预先存在的代码更容易和透明地使用新界面 :

>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
...     contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'

对当地时间歧义的处理

Local Time Disambiguation

In most world locations, there have been and will be times when local clocks are moved back. In those times, intervals are introduced in which local clocks show the same time twice in the same day. In these situations, the information displayed on a local clock (or stored in a Python datetime instance) is insufficient to identify a particular moment in time.
(在大多数世界各地,都有过,或在在将来都有当地的时钟回调的时候。在这些时间里,在同一时间内,当地时钟会同时显示两个时间。在这些情况下,显示在本地时钟(或存储在Python日期时间实例中)的信息不足以识别特定时刻。)

PEP 495 adds the new fold attribute to instances of datetime.datetime and datetime.time classes to differentiate between two moments in time for which local times are the same:
(将新的 fold属性添加到实例 datetime.datetime和datetime.time类中,以区分两个时间点,其中本地时间相同:)

>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0

将Windows文件系统编码更改为UTF-8

  表示文件系统路径最好用str(Unicode)而不是字节来执行。但是,有些情况下使用字节是足够和正确的。

  在Python 3.6之前,在Windows上使用字节路径时可能会导致数据丢失。通过这种改变,现在在Windows上支持使用字节来表示路径,前提是这些字节使用返回的编码(sys.getfilesystemencoding()现在默认为编码)进行编码 'utf-8'。

  不使用str表示路径的应用程序应该使用 os.fsencode()并os.fsdecode()确保其字节被正确编码。要恢复到以前的行为,请设置 PYTHONLEGACYWINDOWSFSENCODING或打电话 sys._enablelegacywindowsfsencoding()。

将Windows控制台编码更改为UTF-8

  Windows上的默认控制台现在将接受所有Unicode字符,并将正确读取的str对象提供给Python代码。sys.stdin, sys.stdout并且sys.stderr现在默认为UTF-8编码。

  此更改仅适用于使用交互式控制台时,而不是重定向文件或管道时。要恢复以前的交互式控制台使用的行为,请设置PYTHONLEGACYWINDOWSSTDIO。

posted @ 2017-11-01 16:01  杨洛平  阅读(4983)  评论(0编辑  收藏  举报