python 3.2的新功能

作者

雷蒙德·赫廷格

本文解释了与3.1相比,Python3.2中的新特性。它着重介绍了一些亮点,并给出了一些例子。有关详细信息,请参阅 Misc/NEWS 文件。

参见

PEP 392 -python 3.2发布计划

PEP 384:定义稳定的ABI

在过去,为一个Python版本构建的扩展模块通常不能与其他Python版本一起使用。尤其是在Windows上,Python的每一个功能版本都需要重建所有想要使用的扩展模块。这个需求是扩展模块可以使用的免费访问Python解释器内部的结果。

有了python 3.2,就有了另一种方法:扩展模块(通过 Py_LIMITED_API 定义 )将自己限制在一个有限的api中)不能使用许多内部构件,而是限制在一组api函数上,这些函数承诺在几个版本中是稳定的。因此,在该模式下为3.2构建的扩展模块也将与3.3、3.4等一起工作。利用内存结构细节的扩展模块仍然可以构建,但是需要为每个功能版本重新编译。

参见

PEP 384 -定义稳定的ABI

由Martin von L_wis撰写的PEP。

PEP 389:argparse命令行分析模块

用于命令行分析的新模块, argparse ,是为了克服 optparse 它不支持位置参数(不仅仅是选项)、子命令、必需选项和其他指定和验证选项的常见模式。

这个模块已经作为第三方模块在社区中取得了广泛的成功。其特点比其前身更加全面, argparse 模块现在是命令行处理的首选模块。由于依赖于旧模块的大量遗留代码,旧模块仍然可用。

下面是一个带注释的示例解析器,它显示了一些功能,比如将结果限制在一组选项中,指定 梅塔伐 在帮助屏幕中,验证是否存在一个或多个位置参数,并生成一个必需的选项::

import argparse
parser = argparse.ArgumentParser(
            description = 'Manage servers',         # main description for help
            epilog = 'Tested on Solaris and Linux') # displayed after help
parser.add_argument('action',                       # argument name
            choices = ['deploy', 'start', 'stop'],  # three allowed values
            help = 'action on each target')         # help msg
parser.add_argument('targets',
            metavar = 'HOSTNAME',                   # var name used in help msg
            nargs = '+',                            # require one or more targets
            help = 'url for target machines')       # help msg explanation
parser.add_argument('-u', '--user',                 # -u or --user option
            required = True,                        # make it a required argument
            help = 'login as user')

对命令字符串调用解析器的示例:

>>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
>>> result = parser.parse_args(cmd.split())
>>> result.action
'deploy'
>>> result.targets
['sneezy.example.com', 'sleepy.example.com']
>>> result.user
'skycaptain'

分析器自动生成的帮助示例:

>>> parser.parse_args('-h'.split())

usage: manage_cloud.py [-h] -u USER
                       {deploy,start,stop} HOSTNAME [HOSTNAME ...]

Manage servers

positional arguments:
  {deploy,start,stop}   action on each target
  HOSTNAME              url for target machines

optional arguments:
  -h, --help            show this help message and exit
  -u USER, --user USER  login as user

Tested on Solaris and Linux

特别好的 argparse 功能是定义子分区的能力,每个子分区都有自己的参数模式和帮助显示:

import argparse
parser = argparse.ArgumentParser(prog='HELM')
subparsers = parser.add_subparsers()

parser_l = subparsers.add_parser('launch', help='Launch Control')   # first subgroup
parser_l.add_argument('-m', '--missiles', action='store_true')
parser_l.add_argument('-t', '--torpedos', action='store_true')

parser_m = subparsers.add_parser('move', help='Move Vessel',        # second subgroup
                                 aliases=('steer', 'turn'))         # equivalent names
parser_m.add_argument('-c', '--course', type=int, required=True)
parser_m.add_argument('-s', '--speed', type=int, default=0)
$ ./helm.py --help                         # top level help (launch and move)
$ ./helm.py launch --help                  # help for launch options
$ ./helm.py launch --missiles              # set missiles=True and torpedos=False
$ ./helm.py steer --course 180 --speed 5   # set movement parameters

参见

PEP 389 -新的命令行分析模块

由史蒂文·贝萨德写的PEP。

升级optparse代码 有关差异的详细信息 optparse .

PEP 391:基于字典的日志配置

这个 logging 模块提供了两种配置,一种样式具有对每个选项的函数调用,另一种样式由保存在 ConfigParser 格式。这些选项没有提供从JSON或YAML文件创建配置的灵活性,也不支持从命令行指定记录器选项所需的增量配置。

为了支持更灵活的样式,模块现在提供 logging.config.dictConfig() 用于使用纯Python字典指定日志配置。配置选项包括格式化程序、处理程序、过滤器和记录器。下面是一个配置字典的工作示例:

{"version": 1,
 "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
                "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}
                },
 "handlers": {"console": {
                   "class": "logging.StreamHandler",
                   "formatter": "brief",
                   "level": "INFO",
                   "stream": "ext://sys.stdout"},
              "console_priority": {
                   "class": "logging.StreamHandler",
                   "formatter": "full",
                   "level": "ERROR",
                   "stream": "ext://sys.stderr"}
              },
 "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}

如果字典存储在一个名为 conf.json ,可以使用如下代码加载和调用:

>>> import json, logging.config
>>> with open('conf.json') as f:
...     conf = json.load(f)
...
>>> logging.config.dictConfig(conf)
>>> logging.info("Transaction completed normally")
INFO    : root           : Transaction completed normally
>>> logging.critical("Abnormal termination")
2011-02-17 11:14:36,694 root            CRITICAL Abnormal termination

参见

PEP 391 -基于字典的日志配置

由Vinay Sajip编写的PEP。

PEP 3148: concurrent.futures 模块

用于创建和管理并发性的代码正在新的顶级命名空间中收集, 同时发生的 . 它的第一个成员是 期货 为管理线程和进程提供统一的高级接口的包。

设计为 concurrent.futures 灵感来自 java.util.concurrent 包裹。在该模型中,正在运行的调用及其结果由 Future 对象,它抽象线程、进程和远程过程调用所共有的特性。该对象支持状态检查(运行或完成)、超时、取消、添加回调以及对结果或异常的访问。

新模块的主要功能是提供一对用于启动和管理调用的执行器类。执行器的目标是使使用现有工具进行并行调用更加容易。它们节省了设置资源池、启动调用、创建结果队列、添加超时处理以及限制线程、进程或远程过程调用总数所需的工作。

理想情况下,每个应用程序应该在多个组件之间共享一个执行器,这样就可以集中管理进程和线程限制。这解决了当每个组件都有自己的资源管理竞争策略时出现的设计挑战。

两个类都使用三种方法共享一个公共接口: submit() 用于调度可调用文件并返回 Future 对象; map() 一次调度多个异步调用,以及 shutdown() 用于释放资源。该类是 context manager 可用于 with 声明,以确保在当前挂起的期货执行完成时自动释放资源。

一个简单的例子 ThreadPoolExecutor 启动四个并行线程以复制文件::

import concurrent.futures, shutil
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
    e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
    e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest4.txt')

参见

PEP 3148 -期货--异步执行计算

布赖恩·昆兰写的PEP。

Code for Threaded Parallel URL reads ,一个使用线程并行获取多个网页的示例。

Code for computing prime numbers in parallel 举个例子 ProcessPoolExecutor .

PEP 3147:PYC存储库目录

python的字节码缓存方案 .pyc 文件在使用多个Python解释器的环境中工作不好。如果一个解释器遇到另一个解释器创建的缓存文件,它将重新编译源文件并覆盖缓存文件,从而失去缓存的好处。

随着Linux发行版与多个版本的Python一起发布,“pyc-battles”的问题变得越来越明显。这些冲突也出现在凯普顿的替代品上,如空腹燕子。

为了解决这个问题,python的导入机制被扩展为对每个解释器使用不同的文件名。现在,他们将寻找“mymodule.cpython-32.pyc”、“mymodule.cpython-33.pyc”和“mymodule.unladen10.pyc”,而不是python 3.2和python 3.3以及unladen吞下每个竞争文件“mymodule.pyc”。为了防止所有这些新文件弄乱源目录, pyc 文件现在被收集到一个存储在包目录下的“uu-pycache”目录中。

除了文件名和目标目录之外,新方案还有一些对程序员可见的方面:

  • 导入的模块现在有一个 __cached__ 存储导入的实际文件名的属性:

    >>> import collections
    >>> collections.__cached__ 
    'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
    
  • 每个解释器唯一的标记可以从 imp 模块:

    >>> import imp
    >>> imp.get_tag() 
    'cpython-32'
    
  • 尝试从导入的文件推断源文件名的脚本现在需要更智能。仅仅从“.pyc”文件名中去掉“c”已经不够了。而是使用 imp 模块:

    >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
    'c:/py32/lib/collections.py'
    >>> imp.cache_from_source('c:/py32/lib/collections.py') 
    'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
    
  • 这个 py_compilecompileall 模块已更新,以反映新的命名约定和目标目录。命令行调用 编译所有 有新选项: -i 用于指定要编译和 -b 这会导致字节码文件被写入它们的遗留位置,而不是 __pycache__ .

  • 这个 importlib.abc 模块已更新为新的 abstract base classes 用于加载字节码文件。过时的ABC, PyLoaderPyPycLoader 已弃用(文档中包含有关如何保持与python 3.1兼容的说明)。

参见

PEP 3147 -PYC存储库目录

Barry Warsaw写的PEP。

PEP 3149:ABI版本标记.so文件

pyc存储库目录允许同时定位多个字节码缓存文件。这个PEP通过为共享对象文件提供一个公共目录和每个版本的不同名称来实现类似的机制。

公共目录是“pyshared”,通过标识python实现(如CPython、 PyPy、Jython等)、主版本号和次版本号以及可选的构建标志(如debug的“d”、pymalloc的“m”、wide unicode的“u”)来区分文件名。对于任意包“foo”,安装分发包时可能会看到以下文件:

/usr/share/pyshared/foo.cpython-32m.so
/usr/share/pyshared/foo.cpython-33md.so

在python本身中,可以从 sysconfig 模块:

>>> import sysconfig
>>> sysconfig.get_config_var('SOABI')       # find the version tag
'cpython-32mu'
>>> sysconfig.get_config_var('EXT_SUFFIX')  # find the full filename extension
'.cpython-32mu.so'

参见

PEP 3149 -ABI版本标记.so文件

Barry Warsaw写的PEP。

PEP 3333:python web服务器网关接口v1.0.1

此信息性PEP阐明了如何通过WSGi协议处理字节/文本问题。面临的挑战是,用 str 类型,即使HTTP协议本身是面向字节的。

PEP区别于所谓的 本地字符串 用于请求/响应头和元数据的 字节串 用于请求和响应的主体。

这个 本地字符串 总是属于类型 str 但只限于代码点之间 U+ 0000 通过 U+0FFF 可转换为字节 Latin-1 编码。这些字符串用于环境字典中的键和值,以及 start_response() 功能。他们必须跟随 RFC 2616 关于编码。也就是说,他们必须 ISO-8859-1 字符或用法 RFC 2047 MIME编码。

对于从python 2移植wsgi应用程序的开发人员,以下是要点:

  • 如果应用程序已经在python 2中使用了头部字符串,则不需要进行任何更改。

  • 如果相反,应用程序编码的输出头或解码的输入头,则需要将头重新编码为Latin-1。例如,使用utf-8编码的输出头使用 h.encode('utf-8') 现在需要使用 h.encode('utf-8').decode('latin-1') .

  • 由应用程序生成或使用 write() 方法必须是字节字符串。这个 start_response() 函数和环境必须使用本机字符串。两者不能混用。

对于将CGI写入wsgi路径或其他CGI风格协议的服务器实现者,即使底层平台可能有不同的约定,用户也必须能够使用本机字符串访问环境。为了弥补这个缺口, wsgiref 模块具有新功能, wsgiref.handlers.read_environ() 用于转换CGI变量 os.environ 返回一个新字典。

参见

PEP 3333 -python web服务器网关接口v1.0.1

菲利普·埃比写的PEP。

其他语言更改

对核心python语言所做的一些较小的更改是:

  • 字符串格式 format()str.format() 获得了格式化字符的新功能 # . 以前,对于二进制、八进制或十六进制的整数,它导致输出分别以“0b”、“0o”或“0x”作为前缀。现在它还可以处理浮点数、复数和小数,从而使输出始终具有小数点,即使后面没有数字。

    >>> format(20, '#o')
    '0o24'
    >>> format(12.34, '#5.0f')
    '  12.'
    

    (由Mark Dickinson提出,Eric Smith于年实施) bpo-7094

  • 还有一个新的 str.format_map() 扩展现有功能的方法 str.format() 任意接受法 mapping 物体。这个新方法可以将字符串格式与Python的许多类似字典的对象(如 defaultdictShelfConfigParserdbm . 它还可以用于自定义 dict 在查找前规范化键或提供 __missing__() 未知键的方法:

    >>> import shelve
    >>> d = shelve.open('tmp.shl')
    >>> 'The {project_name} status is {status} as of {date}'.format_map(d)
    'The testing project status is green as of February 15, 2011'
    
    >>> class LowerCasedDict(dict):
    ...     def __getitem__(self, key):
    ...         return dict.__getitem__(self, key.lower())
    >>> lcd = LowerCasedDict(part='widgets', quantity=10)
    >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd)
    'There are 10 widgets in stock'
    
    >>> class PlaceholderDict(dict):
    ...     def __missing__(self, key):
    ...         return '<{}>'.format(key)
    >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict())
    'Hello <name>, welcome to <location>'
    

(由Raymond Hettinger提出,Eric Smith于年实施) bpo-6081

  • 现在可以用一个安静的选项启动解释器, -q ,以防止在交互模式中显示版权和版本信息。可以使用 sys.flags 属性:

    $ python -q
    >>> sys.flags
    sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,
    optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,
    ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
    

    ( 由Marcin Wojdyr于 bpo-1772833

  • 这个 hasattr() 函数通过调用工作 getattr() 以及检测是否引发异常。此技术允许它检测由 __getattr__()__getattribute__() 否则就不会出现在课堂词典里了。从前, 哈斯塔特 会捕获任何异常,可能会掩盖真正的错误。现在, 哈斯塔特 已拧紧以仅捕获 AttributeError 并让其他异常通过:

    >>> class A:
    ...     @property
    ...     def f(self):
    ...         return 1 // 0
    ...
    >>> a = A()
    >>> hasattr(a, 'f')
    Traceback (most recent call last):
      ...
    ZeroDivisionError: integer division or modulo by zero
    

    (由尤里·塞利万诺夫发现,本杰明·彼得森修复; bpo-9666

  • 这个 str() 浮点数或复数的 repr() . 以前, str() 形式较短,但这只会造成混乱,现在不再需要最短的可能 repr() 默认显示:

    >>> import math
    >>> repr(math.pi)
    '3.141592653589793'
    >>> str(math.pi)
    '3.141592653589793'
    

    ( 由Mark Dickinson提出并实施; bpo-9337

  • memoryview 对象现在有一个 release() 方法,它们现在也支持上下文管理协议。这允许及时释放从原始对象请求缓冲区时获取的任何资源。

    >>> with memoryview(b'abcdefgh') as v:
    ...     print(v.tolist())
    [97, 98, 99, 100, 101, 102, 103, 104]
    

    ( 由Antoine Pitrou添加; bpo-9757

  • 以前,如果名称作为嵌套块中的自由变量出现,则从本地命名空间中删除该名称是非法的::

    def outer(x):
        def inner():
            return x
        inner()
        del x
    

    现在允许这样做。记住,目标 except 子句被清除,因此用于处理python 2.6的代码引发了 SyntaxError 使用python 3.1,现在可以再次使用:

    def f():
        def print_error():
            print(e)
        try:
            something
        except Exception as e:
            print_error()
            # implicit "del e" here
    

    ( 见 bpo-4617

  • 内部 structsequence 工具现在创建tuple的子类。这意味着C结构与返回的结构类似 os.stat()time.gmtime()sys.version_info 现在工作像 named tuple 现在使用期望元组作为参数的函数和方法。这是使C结构与纯Python结构一样灵活的一大进步:

    >>> import sys
    >>> isinstance(sys.version_info, tuple)
    True
    >>> 'Version %d.%d.%d %s(%d)' % sys.version_info 
    'Version 3.2.0 final(0)'
    

    (由Arfrever Frehtes Taifersar Arahesi提出,Benjamin Peterson于年实施) bpo-8413

  • 现在,使用 PYTHONWARNINGS 环境变量作为使用 -W 在命令行:

    $ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
    

    (由Barry Warsaw提出,Philip Jenvey于年实施) bpo-7301

  • 新的警告类别, ResourceWarning ,已添加。当检测到资源消耗或清理的潜在问题时,会发出此消息。默认情况下,它在正常的发布版本中处于静默状态,但可以通过 warnings 模块,或在命令行上。

    A ResourceWarning 在解释程序关闭时发出,如果 gc.garbage 列表不是空的,如果 gc.DEBUG_UNCOLLECTABLE 设置后,将打印所有无法收集的对象。这是为了让程序员知道他们的代码包含对象终结问题。

    A ResourceWarningfile object 在未被显式关闭的情况下被销毁。虽然此类对象的DealLocator确保它关闭底层操作系统资源(通常是文件描述符),但释放对象的延迟可能会产生各种问题,特别是在Windows下。下面是从命令行启用警告的示例:

    $ python -q -Wdefault
    >>> f = open("foo", "wb")
    >>> del f
    __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
    

    (由Antoine Pitrou和Georg Brandl在 bpo-10093bpo-477863

  • range 对象现在支持 index计数 方法。这是使更多对象完全实现 collections.Sequence abstract base class . 因此,该语言将具有更统一的API。此外, range 对象现在支持切片和负索引,即使值大于 sys.maxsize . 这使得 范围 与列表更具互操作性:

    >>> range(0, 100, 2).count(10)
    1
    >>> range(0, 100, 2).index(10)
    5
    >>> range(0, 100, 2)[5]
    10
    >>> range(0, 100, 2)[0:5]
    range(0, 10, 2)
    

    (Daniel Stutzbach在 bpo-9213 ,作者:Alexander Belopolsky bpo-2690 由Nick Coghlan在 bpo-10889

  • 这个 callable() PY2.x中的内置函数已恢复。它提供了使用 abstract base class 以一种像 isinstance(x, collections.Callable)

    >>> callable(max)
    True
    >>> callable(20)
    False
    

    ( 见 bpo-10518

  • python的导入机制现在可以加载安装在路径名中包含非ASCII字符的目录中的模块。这解决了用户的主目录在用户名中使用非ASCII字符的问题。

( 需要维克多·斯廷纳在 bpo-9425

新的、改进的和不推荐使用的模块

Python的标准库经历了大量的维护工作和质量改进。

对于python 3.2来说,最大的新闻是 email 包裹, mailbox 模块,以及 nntplib 模块现在可以在Python3中正确地使用字节/文本模型。首次正确处理混合编码的消息。

在整个标准库中,对编码和文本与字节问题的关注更为谨慎。特别是,与操作系统的交互现在能够更好地使用Windows MBCS编码、支持区域设置的编码或UTF-8交换非ASCII数据。

另一个重要的胜利是为 SSL 连接和安全证书。

此外,更多的类现在实现 context manager 为了支持使用 with 语句。

电子邮件

的可用性 email python 3中的包主要是由R.david murray的大量工作修复的。问题是电子邮件通常是以 bytes 而不是 str 文本,它们可能在一封电子邮件中包含多个编码。因此,必须扩展电子邮件包来解析和生成字节格式的电子邮件。

  • 新功能 message_from_bytes()message_from_binary_file() 和新课程 BytesFeedParserBytesParser 允许将二进制消息数据分析为模型对象。

  • 给定输入到模型的字节数, get_payload() 默认情况下,将解码具有 Content-Transfer-Encoding 属于 8bit 使用mime头中指定的字符集并返回结果字符串。

  • 给定输入到模型的字节数, Generator 将转换具有 Content-Transfer-Encoding 属于 8bit 取而代之的是 7bit Content-Transfer-Encoding .

    带有未编码非ASCII字节的头被认为是 RFC 2047 -使用编码 unknown-8bit 字符集。

  • 一个新类 BytesGenerator 生成字节作为输出,保留用于构建模型的输入中存在的任何未更改的非ASCII数据,包括带有 Content-Transfer-Encoding 属于 8bit .

  • 这个 smtplib SMTP 类现在接受 msg 参数 sendmail() 方法和新方法, send_message() 接受一 Message 对象,并且可以选择获取 from_addrto_addrs 直接来自对象的地址。

(由R.David Murray提议并实施, bpo-4661bpo-10321

元素树

这个 xml.etree.ElementTree 封装及其封装 xml.etree.cElementTree 副本已更新为1.3版。

添加了一些新的有用功能和方法:

有两种方法已被弃用:

  • xml.etree.ElementTree.getchildren() 使用 list(elem) 相反。

  • xml.etree.ElementTree.getiterator() 使用 Element.iter 相反。

有关更新的详细信息,请参阅 Introducing ElementTree 在Fredrik Lundh的网站上。

( 由佛罗伦萨·西克拉纳和弗雷德里克·伦德提供, bpo-6472

功能工具

  • 这个 functools 模块包含一个用于缓存函数调用的新修饰符。 functools.lru_cache() 可以在预期结果相同时将重复查询保存到外部资源。

    例如,向数据库查询函数中添加缓存装饰符可以保存数据库访问以供流行搜索:

    >>> import functools
    >>> @functools.lru_cache(maxsize=300)
    ... def get_phone_number(name):
    ...     c = conn.cursor()
    ...     c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
    ...     return c.fetchone()[0]
    
    >>> for name in user_requests:        
    ...     get_phone_number(name)        # cached lookup
    

    为了帮助选择有效的缓存大小,对封装函数进行检测以跟踪缓存统计信息:

    >>> get_phone_number.cache_info()     
    CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
    

    如果更新了调用列表表,则可以使用以下方法清除缓存中过时的内容:

    >>> get_phone_number.cache_clear()
    

    (由Raymond Hettinger提供,并结合了Jim Baker、Miki Tebeka和Nick Coghlan的设计理念;见 recipe 498245 recipe 577479 bpo-10586bpo-10593

  • 这个 functools.wraps() 装饰师现在添加了 __wrapped__ 指向原始可调用函数的属性。这允许对封装函数进行内省。它也复制 __annotations__ 如果定义。现在,它还优雅地跳过了缺少的属性,例如 __doc__ 可能没有为封装的可调用项定义。

    在上面的示例中,可以通过恢复原始函数来删除缓存:

    >>> get_phone_number = get_phone_number.__wrapped__    # uncached function
    

    (作者:尼克·科格伦和特伦斯·科尔; bpo-9567bpo-3445bpo-8814

  • 为了帮助使用丰富的比较方法编写类,新的修饰器 functools.total_ordering() 将使用现有的平等和不平等的方法来填充剩余的方法。

    例如,提供 __eq____lt__ 将启用 total_ordering() 填写 __le____gt____ge__ ::

    @total_ordering
    class Student:
        def __eq__(self, other):
            return ((self.lastname.lower(), self.firstname.lower()) ==
                    (other.lastname.lower(), other.firstname.lower()))
    
        def __lt__(self, other):
            return ((self.lastname.lower(), self.firstname.lower()) <
                    (other.lastname.lower(), other.firstname.lower()))
    

    total_ordering decorator,其余的比较方法将自动填充。

    ( Raymond Hettinger提供。)

  • 为了帮助从python 2移植程序, functools.cmp_to_key() 函数将旧式比较函数转换为现代函数 key function

    >>> # locale-aware sort order
    >>> sorted(iterable, key=cmp_to_key(locale.strcoll)) 
    

    有关排序示例和简短的排序教程,请参见 Sorting HowTo 辅导的。

    ( Raymond Hettinger提供。)

迭代工具

  • 这个 itertools 模块有一个新的 accumulate() 基于APL的函数模型 scan 操作员和numpy's 积累 功能:

    >>> from itertools import accumulate
    >>> list(accumulate([8, 2, 50]))
    [8, 10, 60]
    
    >>> prob_dist = [0.1, 0.4, 0.2, 0.3]
    >>> list(accumulate(prob_dist))      # cumulative probability distribution
    [0.1, 0.5, 0.7, 1.0]
    

    例如,使用 accumulate()examples for the random module .

    (由Raymond Hettinger提供,并结合Mark Dickinson的设计建议。)

收藏

  • 这个 collections.Counter 类现在有两种形式的就地减法,即 -= 算子 saturating subtraction 和新的 subtract() 常规减法。前者适用于 multisets 只有正计数,后者更适用于允许负计数的用例:

    >>> from collections import Counter
    >>> tally = Counter(dogs=5, cats=3)
    >>> tally -= Counter(dogs=2, cats=8)    # saturating subtraction
    >>> tally
    Counter({'dogs': 3})
    
    >>> tally = Counter(dogs=5, cats=3)
    >>> tally.subtract(dogs=2, cats=8)      # regular subtraction
    >>> tally
    Counter({'dogs': 3, 'cats': -5})
    

    ( Raymond Hettinger提供。)

  • 这个 collections.OrderedDict 类具有新方法 move_to_end() 它获取一个现有的键,并按顺序将其移动到第一个或最后一个位置。

    默认值是将项目移动到最后一个位置。这相当于用 od[k] = od.pop(k) .

    快速移动到结束操作对于重排序条目很有用。例如,有序字典可用于通过将条目从最旧的老化到最近访问的老化来跟踪访问顺序。

    >>> from collections import OrderedDict
    >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])
    >>> list(d)
    ['a', 'b', 'X', 'd', 'e']
    >>> d.move_to_end('X')
    >>> list(d)
    ['a', 'b', 'd', 'e', 'X']
    

    ( Raymond Hettinger提供。)

  • 这个 collections.deque 类增长了两个新方法 count()reverse() 使它们更可替代 list 物体:

    >>> from collections import deque
    >>> d = deque('simsalabim')
    >>> d.count('s')
    2
    >>> d.reverse()
    >>> d
    deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])
    

    ( Raymond Hettinger提供。)

线程加工

这个 threading 模块有一个新的 Barrier 同步类,用于使多个线程等待,直到所有线程都达到一个公共的屏障点。屏障对于确保具有多个前提条件的任务在完成所有前置任务之前都不会运行非常有用。

屏障可以使用任意数量的线程。这是对 Rendezvous 仅为两个线程定义。

作为两相循环屏障, Barrier 对象适合在循环中使用。分开的 填满排水 阶段确保所有线程在它们中的任何一个循环并重新进入屏障之前被释放(排出)。每次循环后屏障完全复位。

使用屏障的示例:

from threading import Barrier, Thread

def get_votes(site):
    ballots = conduct_election(site)
    all_polls_closed.wait()        # do not count until all polls are closed
    totals = summarize(ballots)
    publish(site, totals)

all_polls_closed = Barrier(len(sites))
for site in sites:
    Thread(target=get_votes, args=(site,)).start()

在本例中,屏障强制执行一个规则,即在所有投票结束之前,不能在任何投票站点对投票进行计数。请注意,有屏障的解决方案与 threading.Thread.join() ,但线程保持活动状态,并在越过障碍点后继续执行工作(汇总投票)。

如果任何前置任务可以挂起或延迟,则可以使用可选的 timeout 参数。然后,如果在所有前置任务到达屏障点之前超时时间已过,则释放所有等待线程,并 BrokenBarrierError 引发异常::

def get_votes(site):
    ballots = conduct_election(site)
    try:
        all_polls_closed.wait(timeout=midnight - time.now())
    except BrokenBarrierError:
        lockbox = seal_ballots(ballots)
        queue.put(lockbox)
    else:
        totals = summarize(ballots)
        publish(site, totals)

在这个例子中,屏障强制执行一个更健壮的规则。如果一些选举地点在午夜前还没有结束,那么障碍时间就结束了,选票就被密封起来,放在队列中等待稍后处理。

Barrier Synchronization Patterns 有关如何在并行计算中使用屏障的更多示例。此外,还有一个简单但彻底的解释 The Little Book of Semaphores第3.6节 .

(由Kristj_n Valur J_nsson提供,Jeffrey Yasskin在 bpo-8777

日期时间和时间

  • 这个 datetime 模块具有新类型 timezone 实现了 tzinfo 返回固定的UTC偏移量和时区名称。这使得创建时区感知的日期时间对象更加容易:

    >>> from datetime import datetime, timezone
    
    >>> datetime.now(timezone.utc)
    datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)
    
    >>> datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
    datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
    
  • 也, timedelta 对象现在可以乘以 float 除以 floatint 物体。和 timedelta 对象现在可以彼此分割。

  • 这个 datetime.date.strftime() 方法不再局限于1900年之后的年份。新的支持年份范围是1000到9999(含)。

  • 每当在时间元组中使用两位数字的年份时,解释就由 time.accept2dyear . 默认值为 True 也就是说,在两位数的年份中,根据控制 %y strptime格式。

    从py3.2开始,使用世纪猜想启发式将发出 DeprecationWarning . 相反,建议 time.accept2dyear 被设定为 False 这样大的日期范围就可以不用猜测了:

    >>> import time, warnings
    >>> warnings.resetwarnings()      # remove the default warning filters
    
    >>> time.accept2dyear = True      # guess whether 11 means 11 or 2011
    >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
    Warning (from warnings module):
      ...
    DeprecationWarning: Century info guessed for a 2-digit year.
    'Fri Jan  1 12:34:56 2011'
    
    >>> time.accept2dyear = False     # use the full range of allowable dates
    >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
    'Fri Jan  1 12:34:56 11'
    

    现在有几个函数显著扩展了日期范围。什么时候? time.accept2dyear 是假的 time.asctime() 函数将接受任何适合C int的年份,而 time.mktime()time.strftime() 函数将接受相应操作系统函数支持的完整范围。

(亚历山大·伯罗波尔斯基和维克托·斯廷纳在 bpo-1289118bpo-5094bpo-6641bpo-2706bpo-1777412bpo-8013bpo-10827

数学

这个 math 模块已更新为受C99标准启发的六个新功能。

这个 isfinite() 函数提供了一种可靠和快速的方法来检测特殊值。它返回 True 对于普通数字和 False 对于 Nan无穷

>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]

这个 expm1() 函数计算 e**x-1 对于小值 x 在不造成精度损失的情况下,通常会伴随着几乎相等数量的减法:

>>> from math import expm1
>>> expm1(0.013671875)   # more accurate way to compute e**x-1 for a small x
0.013765762467652909

这个 erf() 函数计算概率积分或 Gaussian error function . 互补误差函数, erfc()1 - erf(x)

>>> from math import erf, erfc, sqrt
>>> erf(1.0/sqrt(2.0))   # portion of normal distribution within 1 standard deviation
0.682689492137086
>>> erfc(1.0/sqrt(2.0))  # portion of normal distribution outside 1 standard deviation
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0

这个 gamma() 函数是阶乘函数的连续扩展。有关详细信息,请参阅https://en.wikipedia.org/wiki/gamma_函数。因为函数与阶乘有关,所以即使对于 x ,所以还有一个 lgamma() 用于计算γ函数自然对数的函数:

>>> from math import gamma, lgamma
>>> gamma(7.0)           # six factorial
720.0
>>> lgamma(801.0)        # log(800 factorial)
4551.950730698041

( 马克·狄金森供稿)

ABC公司

这个 abc 模块现在支持 abstractclassmethod()abstractstaticmethod() .

这些工具使定义 abstract base class 这需要一个特别的 classmethod()staticmethod() 待实施:

class Temperature(metaclass=abc.ABCMeta):
    @abc.abstractclassmethod
    def from_fahrenheit(cls, t):
        ...
    @abc.abstractclassmethod
    def from_celsius(cls, t):
        ...

( Daniel Urban提交的补丁; bpo-5867

输入输出

这个 io.BytesIO 有了新方法, getbuffer() 提供类似于 memoryview() .它创建数据的可编辑视图而不进行复制。缓冲区的随机访问和对切片表示法的支持非常适合就地编辑:

>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11

>>> def change_location(buffer, record_number, location):
...     start = record_number * REC_LEN + LOC_START
...     buffer[start: start+LOC_LEN] = location

>>> import io

>>> byte_stream = io.BytesIO(
...     b'G3805  storeroom  Main chassis    '
...     b'X7899  shipping   Reserve cog     '
...     b'L6988  receiving  Primary sprocket'
... )
>>> buffer = byte_stream.getbuffer()
>>> change_location(buffer, 1, b'warehouse  ')
>>> change_location(buffer, 0, b'showroom   ')
>>> print(byte_stream.getvalue())
b'G3805  showroom   Main chassis    '
b'X7899  warehouse  Reserve cog     '
b'L6988  receiving  Primary sprocket'

(由Antoine Pitrou在 bpo-5506

瑞普利布

写作时 __repr__() 方法对于自定义容器,很容易忘记处理成员引用回容器本身的情况。python的内置对象,例如 listset 通过在表示字符串的递归部分显示“…”来处理自引用。

帮助写这样的 __repr__() 方法, reprlib 模块有一个新的装饰器, recursive_repr() ,用于检测对 __repr__() 替换占位符字符串::

>>> class MyList(list):
...     @recursive_repr()
...     def __repr__(self):
...         return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>

(由Raymond Hettinger在 bpo-9826bpo-9840

登录

除了上面描述的基于字典的配置之外, logging 软件包还有许多其他的改进。

日志文档已由 basic tutorial 一个 advanced tutorial A和A cookbook 记录配方。这些文档是了解日志记录的最快方法。

这个 logging.basicConfig() 设置功能获得 风格 参数来支持三种不同类型的字符串格式。对于传统格式,默认为“%”,对于新格式,可以设置为“”。 str.format() 样式,或者对于由提供的外壳样式格式,可以设置为“$”。 string.Template . 以下三种配置等效:

>>> from logging import basicConfig
>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")
>>> basicConfig(style='{', format="{name} -> {levelname} {message}")
>>> basicConfig(style='$', format="$name -> $levelname: $message")

如果在日志事件发生之前未设置任何配置,则现在有一个默认配置使用 StreamHandler 指向 sys.stderr 对于事件 WARNING 水平或更高。以前,在设置配置之前发生的事件将引发异常或根据 logging.raiseExceptions . 新的默认处理程序存储在 logging.lastResort .

过滤器的使用已经简化。而不是创建 Filter 对象,谓词可以是返回 TrueFalse .

还有一些其他的改进增加了灵活性和简化了配置。有关python 3.2中更改的完整列表,请参阅模块文档。

csv

这个 csv 模块现在支持新方言, unix_dialect ,它适用于所有字段和传统的UNIX样式 '\n' 作为行终止符。注册方言名为 unix .

这个 csv.DictWriter 有了新方法, writeheader() 用于写出首行以记录字段名:

>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
...     {'name': 'tom', 'dept': 'accounting'},
...     {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"

(Jay Talbot在 bpo-5975 以及Ed Abraham在年提出的新方法。 bpo-1537721

contextlib

有一个新的稍微令人兴奋的工具 ContextDecorator 这有助于创建 context manager 作为一个函数修饰器,它具有双重功能。

为了方便起见,此新功能由 contextmanager() 所以不需要额外的努力来支持这两个角色。

基本思想是上下文管理器和函数修饰器都可以用于操作前和操作后封装器。上下文管理器使用 with 语句和函数修饰符将一组语句封装在函数中。因此,有时需要编写一个可以在任一角色中使用的操作前或操作后封装器。

例如,有时用一个记录器封装函数或语句组很有用,该记录器可以跟踪进入时间和退出时间。不是同时为任务编写函数修饰器和上下文管理器, contextmanager() 在单个定义中提供两种功能:

from contextlib import contextmanager
import logging

logging.basicConfig(level=logging.INFO)

@contextmanager
def track_entry_and_exit(name):
    logging.info('Entering: %s', name)
    yield
    logging.info('Exiting: %s', name)

以前,它只能用作上下文管理器:

with track_entry_and_exit('widget loader'):
    print('Some time consuming activity goes here')
    load_widget()

现在,它也可以用作装饰:

@track_entry_and_exit('widget loader')
def activity():
    print('Some time consuming activity goes here')
    load_widget()

试图同时完成两个角色会对技术造成一些限制。上下文管理器通常具有返回参数的灵活性,该参数可由 with 语句,但函数修饰符没有并行语句。

在上面的示例中,对于 track_entry_and_exit 上下文管理器返回日志记录实例,以在封闭语句体中使用。

(迈克尔·福德在 bpo-9110

小数和分数

Mark Dickinson精心设计了一个优雅高效的方案,以确保不同的数字数据类型在其实际值相等时具有相同的hash值。 (bpo-8188 ):

assert hash(Fraction(3, 2)) == hash(1.5) == \
       hash(Decimal("1.5")) == hash(complex(1.5, 0))

一些散列细节是通过一个新属性公开的, sys.hash_info ,它描述hash值的位宽度、质数模、的hash值 无穷nan 以及用于数字虚部的乘法器:

>>> sys.hash_info 
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)

限制各种数字类型的互操作性的早期决定已经放宽。在诸如 Decimal('1.1') + float('1.1') 因为后者在构造二进制浮点的过程中会丢失信息。但是,由于现有的浮点值可以无损地转换为十进制或有理表示,因此将它们添加到构造函数中并支持混合类型比较是有意义的。

fractions.Fraction 所以 from_float()from_decimal() 不再需要方法 (bpo-8294 ):

>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)

另一个有用的变化 decimal 模块是指 Context.clamp 属性现在是公共的。这在创建与IEEE754中指定的十进制交换格式相对应的上下文时很有用(请参见 bpo-8540

(由马克·狄金森和雷蒙德·赫廷格提供。)

FTP协议

这个 ftplib.FTP 类现在支持上下文管理协议无条件地使用 socket.error 异常并在完成时关闭ftp连接:

>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
        ftp.login()
        ftp.dir()

'230 Anonymous login ok, restrictions apply.'
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 .
dr-xr-xr-x   9 ftp      ftp           154 May  6 10:43 ..
dr-xr-xr-x   5 ftp      ftp          4096 May  6 10:43 CentOS
dr-xr-xr-x   3 ftp      ftp            18 Jul 10  2008 Fedora

其他文件,如对象 mmap.mmapfileinput.input() 还增加了自动关闭上下文管理器:

with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
    for line in f:
        process(line)

(由Tarek Ziad_和Giampaolo Rodol_在 bpo-4972 和乔治·布兰德 bpo-8046bpo-1286

这个 FTP_TLS 类现在接受 context 参数,它是 ssl.SSLContext 对象,允许将SSL配置选项、证书和私钥绑定到单个(可能是长期存在的)结构中。

(由Giampaolo Rodol_提供; bpo-8806

波彭

这个 os.popen()subprocess.Popen() 功能现在支持 with 用于自动关闭文件描述符的语句。

(由Antoine Pitrou和Brian Curtin在 bpo-7461bpo-10554

选择

这个 select 模块现在公开了一个新的常量属性, PIPE_BUF ,它给出了保证在以下情况下不阻塞的最小字节数: select.select() 说一根管子可以用来写字了。

>>> import select
>>> select.PIPE_BUF  
512

(在Unix系统上可用。S_bastien sabl_in补丁 bpo-9862

gzip和zipfile

gzip.GzipFile 现在实现 io.BufferedIOBase abstract base class (除 truncate() )它还有一个 peek() 方法和支持不可搜索的以及零填充的文件对象。

这个 gzip 模块还获得 compress()decompress() 函数可以更方便地进行内存压缩和解压。请记住,文本需要编码为 bytes 压缩和解压缩之前:

>>> import gzip
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode()                        # convert to utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42]      # decompress and convert to text
'Three shall be the number thou shalt count'

(由Anand B.Pillai在 bpo-3488 由Antoine Pitrou,NIR助手和Brian Curtin在 bpo-9962bpo-1675951bpo-7471bpo-2846

此外, zipfile.ZipExtFile 类在内部进行了重写,以表示存储在存档中的文件。新的实现速度明显更快,可以用 io.BufferedReader 更多加速的对象。它还解决了交错调用 readreadline 给出了错误的结果。

(NIR助手在 bpo-7610

tarfile

这个 TarFile 类现在可以用作上下文管理器。此外,其 add() 方法有一个新选项, 滤波器 控制哪些文件添加到存档中,并允许编辑文件元数据。

新的 滤波器 选项取代了旧的、不太灵活的 排除 现在已弃用的参数。如果指定,则可选 滤波器 参数必须是 keyword argument . 用户提供的筛选器函数接受 TarInfo 对象并返回更新的 TarInfo 对象,或者如果希望排除文件,函数可以返回 None ::

>>> import tarfile, glob

>>> def myfilter(tarinfo):
...     if tarinfo.isfile():             # only save real files
...         tarinfo.uname = 'monty'      # redact the user name
...         return tarinfo

>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
...     for filename in glob.glob('*.txt'):
...         tf.add(filename, filter=myfilter)
...     tf.list()
-rw-r--r-- monty/501        902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501        123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501       3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501        124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501       1399 2011-01-26 17:59:11 semaphore_notes.txt

(由Tarek Ziad_提议,由Lars Gust_bel in实施) bpo-6856

hashlib

这个 hashlib 模块有两个新的常量属性,列出了保证在所有实现中都存在的hash算法以及当前实现中可用的hash算法:

>>> import hashlib

>>> hashlib.algorithms_guaranteed
{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}

>>> hashlib.algorithms_available
{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}

(由Carl Chenet在 bpo-7418

AST

这个 ast 模块有一个非常好的通用工具,可以使用python文本语法安全地评估表达式字符串。这个 ast.literal_eval() 函数作为内置函数的安全替代方案 eval() 容易被滥用的功能。python 3.2增加了 bytesset 支持类型列表的文本:字符串、字节、数字、元组、列表、dict、set、booleans和 None .

>>> from ast import literal_eval

>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}

>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
  ...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>

(由Benjamin Peterson和Georg Brandl实施。)

操作系统

不同的操作系统对文件名和环境变量使用不同的编码。这个 os 模块提供两个新功能, fsencode()fsdecode() ,用于编码和解码文件名:

>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'

有些操作系统允许直接访问环境中的编码字节。如果是这样, os.supports_bytes_environ 常数将为真。

要直接访问编码的环境变量(如果可用),请使用 os.getenvb() 功能或用途 os.environb 是的字节版本 os.environ .

(维克多·斯廷纳供稿)

shutil

这个 shutil.copytree() 函数有两个新选项:

  • ignore_dangling_symlinks 什么时候 symlinks=False 这样函数就可以复制一个由符号链接指向的文件,而不是符号链接本身。如果文件不存在,此选项将使所引发的错误静音。

  • copy_function :是用于复制文件的可调用文件。 shutil.copy2() 默认情况下使用。

(由Tarek Ziad_提供。)

此外, shutil 模块现在支持 archiving operations 对于zipfiles、未压缩tarfiles、gzipped tarfiles和bzipped tarfiles。还有一些功能可以注册额外的存档文件格式(例如XZ压缩tarfiles或自定义格式)。

主要功能是 make_archive()unpack_archive() . 默认情况下,两者都在当前目录上操作(可以通过 os.chdir() )以及任何子目录。需要使用完整路径名指定存档文件名。存档步骤是非破坏性的(原始文件保持不变)。

>>> import shutil, pprint

>>> os.chdir('mydata')  # change to the source directory
>>> f = shutil.make_archive('/var/backup/mydata',
...                         'zip')      # archive the current directory
>>> f                                   # show the name of archive
'/var/backup/mydata.zip'
>>> os.chdir('tmp')                     # change to an unpacking
>>> shutil.unpack_archive('/var/backup/mydata.zip')  # recover the data

>>> pprint.pprint(shutil.get_archive_formats())  # display known formats
[('bztar', "bzip2'ed tar-file"),
 ('gztar', "gzip'ed tar-file"),
 ('tar', 'uncompressed tar file'),
 ('zip', 'ZIP file')]

>>> shutil.register_archive_format(     # register a new archive format
...     name='xz',
...     function=xz.compress,           # callable archiving function
...     extra_args=[('level', 8)],      # arguments to the function
...     description='xz compression'
... )

(由Tarek Ziad_提供。)

sqlite3

这个 sqlite3 模块已更新为pysqlite版本2.6.0。它有两个新功能。

(R.David Murray和Shashwat Anand提供; bpo-8845

HTML

一个新的 html 模块的引入只有一个功能, escape() ,用于从HTML标记转义保留字符:

>>> import html
>>> html.escape('x > 2 && x < 7')
'x &gt; 2 &amp;&amp; x &lt; 7'

Socket

这个 socket 模块有两个新的改进。

  • socket对象现在有一个 detach() 方法,它将套接字置于关闭状态,而不实际关闭基础文件描述符。然后,可以将后者用于其他目的。(由Antoine Pitrou添加; bpo-8524

  • socket.create_connection() 现在支持上下文管理协议无条件地使用 socket.error 异常并在完成后关闭套接字。(由Giampaolo Rodol_提供; bpo-9794

SSL

这个 ssl 模块添加了许多功能,以满足安全(加密、认证)互联网连接的常见要求:

  • 一个新类, SSLContext ,用作持久性SSL数据(如协议设置、证书、私钥和各种其他选项)的容器。它包括一个 wrap_socket() 用于从SSL上下文创建SSL套接字。

  • 新功能, ssl.match_hostname() ,通过实现HTTPS规则(从 RFC 2818 )也适用于其他协议。

  • 这个 ssl.wrap_socket() 构造函数函数现在接受 密码 参数。这个 密码 字符串使用中描述的格式列出允许的加密算法 OpenSSL documentation _.

  • 当与最新版本的openssl链接时, ssl 模块现在支持对TLS协议的服务器名称指示扩展,允许在单个IP端口上使用不同证书的多个“虚拟主机”。此扩展仅在客户端模式下受支持,并通过传递 server_hostname 参数 ssl.SSLContext.wrap_socket() .

  • 已将各种选项添加到 ssl 模块,如 OP_NO_SSLv2 这将禁用不安全和过时的SSLV2协议。

  • 扩展现在加载所有openssl密码和摘要算法。如果某些SSL证书无法验证,则报告为“未知算法”错误。

  • 现在可以使用模块属性访问正在使用的OpenSSL版本。 ssl.OPENSSL_VERSION (字符串) ssl.OPENSSL_VERSION_INFO (5元组),以及 ssl.OPENSSL_VERSION_NUMBER (整数)

(由Antoine Pitrou在 bpo-8850bpo-1589bpo-8322bpo-5639bpo-4870bpo-8484bpo-8321

NNTP

这个 nntplib 模块有一个改进的实现,具有更好的字节和文本语义以及更实用的API。这些改进打破了与Python3.1中的nntplib版本的兼容性,后者本身部分功能不正常。

通过隐式(使用 nntplib.NNTP_SSL )和明确的(使用 nntplib.NNTP.starttls() )还添加了TLS。

(由Antoine Pitrou在 bpo-9360 安德鲁·万特在 bpo-1926

证书

http.client.HTTPSConnectionurllib.request.HTTPSHandlerurllib.request.urlopen() 现在采用可选参数,允许根据一组证书颁发机构检查服务器证书,这是在公开使用HTTPS时建议的。

(由Antoine Pitrou添加, bpo-9003

IMAPLIB

已通过新的 imaplib.IMAP4.starttls 方法。

(由Lorenzo M.Catucci和Antoine Pitrou提供, bpo-4471

http.client

http.client 模块。不再支持旧式HTTP 0.9简单响应,并且 strict 参数在所有类中都已弃用。

这个 HTTPConnectionHTTPSConnection 课程现在有一个 source_address (主机、端口)元组的参数,指示从何处建立HTTP连接。

对证书检查和HTTPS虚拟主机的支持已添加到 HTTPSConnection .

这个 request() 连接对象上的方法允许可选 body 参数是这样的 file object 可用于提供请求的内容。很方便, body 参数现在也接受 iterable 对象,只要它包含一个显式 Content-Length 标题。这个扩展接口比以前灵活得多。

要通过代理服务器建立HTTPS连接,需要 set_tunnel() 为HTTP连接隧道设置主机和端口的方法。

以匹配 http.server HTTP客户端库现在也用ISO-8859-1(拉丁语-1)编码头。它已经在为传入的报头执行此操作,因此现在对于传入和传出的通信量,该行为是一致的。(见Armin Ronacher在 bpo-10980

单元测试

UnitTest模块有许多改进,支持包的测试发现、更容易在交互式提示下进行实验、新的测试用例方法、改进的测试失败诊断消息以及更好的方法名称。

  • 命令行调用 python -m unittest 现在可以接受文件路径而不是运行特定测试的模块名称 (bpo-10620 )新的测试发现可以在包中找到测试,从顶级目录中找到任何可导入的测试。顶级目录可以用 -t 选项,用于将文件与 -p 以及一个用于开始发现的目录 -s

    $ python -m unittest discover -s my_proj_dir -p _test.py
    

    (迈克尔·福德供稿)

  • 在交互式提示下进行实验现在更容易了,因为 unittest.case.TestCase 类现在可以在没有参数的情况下实例化:

    >>> from unittest import TestCase
    >>> TestCase().assertEqual(pow(2, 3), 8)
    

    (迈克尔·福德供稿)

  • 这个 unittest 模块有两种新方法, assertWarns()assertWarnsRegex() 要验证给定的警告类型是否由测试代码触发,请执行以下操作:

    with self.assertWarns(DeprecationWarning):
        legacy_function('XYZ')
    

    (由Antoine Pitrou提供, bpo-9754

    另一种新方法, assertCountEqual() 用于比较两个iterables,以确定其元素计数是否相等(是否存在相同元素,且出现次数相同,而不管顺序如何)::

    def test_anagram(self):
        self.assertCountEqual('algorithm', 'logarithm')
    

    ( Raymond Hettinger提供。)

  • UnitTest模块的一个主要功能是在测试失败时产生有意义的诊断。在可能的情况下,记录故障和输出差异。这对于分析失败测试运行的日志文件尤其有用。然而,由于差异有时会很大,所以有一个新的 maxDiff 设置显示的最大差异长度的属性。

  • 此外,模块中的方法名也进行了一些清理。

    例如, assertRegex() 是的新名称 assertRegexpMatches() 因为测试使用了 re.search() 不是 re.match() . 现在,使用正则表达式的其他方法的命名是使用短格式“regex”而不是“regexp”——这与其他UnitTest实现中使用的名称相匹配,与python的旧名称相匹配。 re 模块,有明确的驼色外壳。

    (由Raymond Hettinger提供,Ezio Melotti实施。)

  • 为了提高一致性,一些长期存在的方法别名正被弃用,取而代之的是首选名称:

    旧名

    类似于的名字

    assert_()

    assertTrue()

    assertEquals()

    assertEqual()

    assertNotEquals()

    assertNotEqual()

    assertAlmostEquals()

    assertAlmostEqual()

    assertNotAlmostEquals()

    assertNotAlmostEqual()

    同样地, TestCase.fail* python 3.1中不推荐使用的方法应该在python 3.3中删除。也看到 不推荐使用的别名 节中 unittest 文档。

    (由Ezio Melotti提供; bpo-9424

  • 这个 assertDictContainsSubset() 方法已被弃用,因为它是用错误的参数顺序实现的。这就产生了难以调试的光学错觉 TestCase().assertDictContainsSubset({{'a':1, 'b':2}}, {{'a':1}}) 会失败。

    ( Raymond Hettinger提供。)

随机的

中的整数方法 random 模块现在可以更好地生成均匀分布。以前,他们用 int(n*random()) 每次都有轻微的偏差 n 不是二的力量。现在,从一个范围到下一个二次方进行多个选择,并且只有当一个选择落在该范围内时才保留该选择。 0 <= x < n . 受影响的功能和方法有 randrange()randint()choice()shuffle()sample() .

(由Raymond Hettinger提供; bpo-9025

poplib

POP3_SSL 类现在接受 context 参数,它是 ssl.SSLContext 对象,允许将SSL配置选项、证书和私钥绑定到单个(可能是长期存在的)结构中。

(由Giampaolo Rodol_提供; bpo-8807

异步内核

asyncore.dispatcher 现在提供了 handle_accepted() 方法返回 (sock, addr) 当实际建立了与新远程端点的连接时调用的对。这个应该用来代替旧的 handle_accept() 避免用户调用 accept() 直接。

(由Giampaolo Rodol_提供; bpo-6706

临时文件

这个 tempfile 模块有一个新的上下文管理器, TemporaryDirectory 它提供了对临时目录的简单确定性清理:

with tempfile.TemporaryDirectory() as tmpdirname:
    print('created temporary dir:', tmpdirname)

(由Neil Schemenauer和Nick Coghlan提供; bpo-5178

检查

  • 这个 inspect 模块具有新功能 getgeneratorstate() 要轻松识别生成器迭代器的当前状态:

    >>> from inspect import getgeneratorstate
    >>> def gen():
    ...     yield 'demo'
    >>> g = gen()
    >>> getgeneratorstate(g)
    'GEN_CREATED'
    >>> next(g)
    'demo'
    >>> getgeneratorstate(g)
    'GEN_SUSPENDED'
    >>> next(g, None)
    >>> getgeneratorstate(g)
    'GEN_CLOSED'
    

    (由Rodolpho Eckhardt和Nick Coghlan提供, bpo-10220

  • 为了在不激活动态属性的情况下支持查找,请 inspect 模块具有新功能, getattr_static() .不像 hasattr() ,这是一个真正的只读搜索,保证在搜索时不会更改状态::

    >>> class A:
    ...     @property
    ...     def f(self):
    ...         print('Running')
    ...         return 10
    ...
    >>> a = A()
    >>> getattr(a, 'f')
    Running
    10
    >>> inspect.getattr_static(a, 'f')
    <property object at 0x1022bd788>
    

(迈克尔·福德供稿)

pydoc

这个 pydoc 模块现在提供了一个改进了很多的Web服务器界面,以及一个新的命令行选项。 -b 要自动打开浏览器窗口以显示该服务器:

$ pydoc3.2 -b

(由罗恩·亚当提供; bpo-2001

数字化信息系统

这个 dis 模块获得了两个新的代码检查功能, code_info()show_code() . 两者都为提供的函数、方法、源代码字符串或代码对象提供详细的代码对象信息。前者返回字符串,后者打印:

>>> import dis, random
>>> dis.show_code(random.choice)
Name:              choice
Filename:          /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
Argument count:    2
Kw-only arguments: 0
Number of locals:  3
Stack size:        11
Flags:             OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: 'Choose a random element from a non-empty sequence.'
   1: 'Cannot choose from an empty sequence'
Names:
   0: _randbelow
   1: len
   2: ValueError
   3: IndexError
Variable names:
   0: self
   1: seq
   2: i

此外, dis() 函数现在接受字符串参数,以便 dis(compile(s, '', 'eval')) 可以缩短为 dis(s) ::

>>> dis('3*x+1 if x%2==1 else x//2')
  1           0 LOAD_NAME                0 (x)
              3 LOAD_CONST               0 (2)
              6 BINARY_MODULO
              7 LOAD_CONST               1 (1)
             10 COMPARE_OP               2 (==)
             13 POP_JUMP_IF_FALSE       28
             16 LOAD_CONST               2 (3)
             19 LOAD_NAME                0 (x)
             22 BINARY_MULTIPLY
             23 LOAD_CONST               1 (1)
             26 BINARY_ADD
             27 RETURN_VALUE
        >>   28 LOAD_NAME                0 (x)
             31 LOAD_CONST               0 (2)
             34 BINARY_FLOOR_DIVIDE
             35 RETURN_VALUE

综上所述,这些改进使得我们更容易探索CPython是如何实现的,并亲自了解语言语法在幕后的作用。

(由Nick Coghlan在 bpo-9147

数据库管理

所有数据库模块现在都支持 get()setdefault() 方法。

(由Ray Allen在 bpo-9523

C型

一种新型的, ctypes.c_ssize_t 表示C ssize_t 数据类型。

网站

这个 site 模块有三个新功能,可用于报告给定python安装的详细信息。

>>> import site
>>> site.getsitepackages()
['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
 '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
 '/Library/Python/3.2/site-packages']
>>> site.getuserbase()
'/Users/raymondhettinger/Library/Python/3.2'
>>> site.getusersitepackages()
'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'

方便的是,可以直接从命令行访问站点的某些功能:

$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages

(由Tarek Ziad_在 bpo-6693

系统配置

新的 sysconfig 模块使得发现不同平台和安装的安装路径和配置变量变得非常简单。

该模块提供平台和版本信息的简单访问功能:

它还提供对路径和变量的访问,这些路径和变量对应于 distutils . 这些包括 posix_prefixposix_homeposix_userntnt_useros2os2_home

还有一个方便的命令行界面:

C:\Python32>python -m sysconfig
Platform: "win32"
Python version: "3.2"
Current installation scheme: "nt"

Paths:
        data = "C:\Python32"
        include = "C:\Python32\Include"
        platinclude = "C:\Python32\Include"
        platlib = "C:\Python32\Lib\site-packages"
        platstdlib = "C:\Python32\Lib"
        purelib = "C:\Python32\Lib\site-packages"
        scripts = "C:\Python32\Scripts"
        stdlib = "C:\Python32\Lib"

Variables:
        BINDIR = "C:\Python32"
        BINLIBDEST = "C:\Python32\Lib"
        EXE = ".exe"
        INCLUDEPY = "C:\Python32\Include"
        LIBDEST = "C:\Python32\Lib"
        SO = ".pyd"
        VERSION = "32"
        abiflags = ""
        base = "C:\Python32"
        exec_prefix = "C:\Python32"
        platbase = "C:\Python32"
        prefix = "C:\Python32"
        projectbase = "C:\Python32"
        py_version = "3.2"
        py_version_nodot = "32"
        py_version_short = "3.2"
        srcdir = "C:\Python32"
        userbase = "C:\Documents and Settings\Raymond\Application Data\Python"

(由Tarek Ziad_搬出distutils。)

pdb

这个 pdb 调试器模块获得了一些可用性改进:

  • pdb.py 现在有一个 -c 执行命令的选项 .pdbrc 脚本文件。

  • A .pdbrc 脚本文件可以包含 continuenext 继续调试的命令。

  • 这个 Pdb 类构造函数现在接受 小号 参数。

  • 新命令: l(list)ll(long list)source 用于列出源代码。

  • 新命令: displayundisplay 用于显示或隐藏表达式的值(如果已更改)。

  • 新命令: interact 用于启动包含当前作用域中的全局和本地名称的交互式解释程序。

  • 断点可以通过断点编号清除。

(由乔治布兰德,安东尼奥库尼和伊利亚桑德勒贡献。)

配置分析器

这个 configparser 修改模块以提高默认解析器及其支持的ini语法的可用性和可预测性。老年人 ConfigParser 为了支持 SafeConfigParser 又被重新命名为 ConfigParser . 默认情况下,对内联注释的支持现在已关闭,单个配置源中不允许有节或选项重复。

配置分析器获得了一个基于映射协议的新API::

>>> parser = ConfigParser()
>>> parser.read_string("""
... [DEFAULT]
... location = upper left
... visible = yes
... editable = no
... color = blue
...
... [main]
... title = Main Menu
... color = green
...
... [options]
... title = Options
... """)
>>> parser['main']['color']
'green'
>>> parser['main']['editable']
'no'
>>> section = parser['options']
>>> section['title']
'Options'
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'

新的API是在经典API之上实现的,因此定制的解析器子类应该能够在不做修改的情况下使用它。

现在可以自定义配置分析器接受的ini文件结构。用户可以指定可选选项/值分隔符和注释前缀,更改 DEFAULT 分段或切换插值语法。

支持插入式插补,包括附加的插补处理程序 ExtendedInterpolation ::

>>> parser = ConfigParser(interpolation=ExtendedInterpolation())
>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
...                   'custom': {'prefix': '/usr/local'}})
>>> parser.read_string("""
... [buildout]
... parts =
...   zope9
...   instance
... find-links =
...   ${buildout:directory}/downloads/dist
...
... [zope9]
... recipe = plone.recipe.zope9install
... location = /opt/zope
...
... [instance]
... recipe = plone.recipe.zope9instance
... zope9-location = ${zope9:location}
... zope-conf = ${custom:prefix}/etc/zope.conf
... """)
>>> parser['buildout']['find-links']
'\n/home/ambv/zope9/downloads/dist'
>>> parser['instance']['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance = parser['instance']
>>> instance['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance['zope9-location']
'/opt/zope'

还引入了一些较小的功能,例如支持在读取操作中指定编码、为get函数指定回退值或直接从字典和字符串中读取。

(所有由_Ukasz Langa提供的更改。)

urllib.parse

urllib.parse 模块。

这个 urlparse() 功能现在支持 IPv6 地址如中所述 RFC 2732

>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') 
ParseResult(scheme='http',
            netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
            path='/foo/',
            params='',
            query='',
            fragment='')

这个 urldefrag() 函数现在返回 named tuple ::

>>> r = urllib.parse.urldefrag('http://python.org/about/#target')
>>> r
DefragResult(url='http://python.org/about/', fragment='target')
>>> r[0]
'http://python.org/about/'
>>> r.fragment
'target'

而且, urlencode() 函数现在更加灵活,可以接受字符串或字节类型 查询 参数。如果是字符串,则 safeencodingerrors 参数发送到 quote_plus() 编码:

>>> urllib.parse.urlencode([
...      ('type', 'telenovela'),
...      ('name', '¿Dónde Está Elisa?')],
...      encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'

详述 分析ASCII编码字节 ,所有的 urllib.parse 函数现在接受ASCII编码的字节字符串作为输入,只要它们不与常规字符串混合。如果将ASCII编码的字节字符串作为参数提供,则返回类型也将是一个ASCII编码的字节字符串:

>>> urllib.parse.urlparse(b'http://www.python.org:80/about/') 
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
                 path=b'/about/', params=b'', query=b'', fragment=b'')

(由Nick Coghlan、Dan Mahn和Senthil Kumaran在 bpo-2987bpo-5468bpo-9873

信箱

感谢R.David Murray的共同努力, mailbox 已为python 3.2修复了模块。问题是,邮箱最初是用文本界面设计的,但电子邮件最好用 bytes 因为消息的各个部分可能有不同的编码。

解决方案利用了 email 包对解析任意电子邮件的二进制支持。此外,该解决方案还需要进行一些API更改。

如预期的那样, add() 方法 mailbox.Mailbox 对象现在接受二进制输入。

StringIO 文本文件输入被弃用。此外,如果使用非ASCII字符,则字符串输入将提前失败。以前,在以后的步骤中处理电子邮件时,它会失败。

还支持二进制输出。这个 get_file() 方法现在以二进制模式返回一个文件(以前它错误地将文件设置为文本模式)。还有一个新的 get_bytes() 返回 bytes 对应于给定的 key .

仍然可以使用旧API获取非二进制输出 get_string() 方法,但这种方法不是很有用。相反,最好从 Message 对象或从二进制输入加载它们。

(R.David Murray在Steffen Daode Nurpmeso的努力和Victor Stinner在 bpo-9124

turtle表演

的演示代码 turtle 模块已从 Demo 目录到主库。它包括十几个带有生动显示的示例脚本。在上 sys.path ,现在可以直接从命令行运行:

$ python -m turtledemo

(由Alexander Belopolsky在 bpo-10199

多线程

  • 对并发运行的python线程(通常称为 GIL 或全局解释器锁)已被重写。其中的目标是更可预测的交换间隔,以及由于锁争用和随后的系统调用的数量而减少的开销。允许线程切换的“检查间隔”概念已经被放弃,取而代之的是以秒为单位的绝对持续时间。此参数可通过 sys.setswitchinterval() . 它当前默认为5毫秒。

    有关实现的其他详细信息可以从 python-dev mailing-list message (但是,此消息中公开的“优先级请求”并未保留以供包含)。

    (安托万·皮特鲁供稿)

  • 常规锁和递归锁现在接受可选的 timeout 他们的参数 acquire() 方法。(安托万·皮特鲁提供; bpo-7316

  • 同样地, threading.Semaphore.acquire() 也获得了 timeout 参数。(由Torsten Landschoff提供; bpo-850728

  • 通过使用pthreads,平台上的信号现在可以中断常规和递归锁获取。这意味着在获取锁时死锁的python程序可以通过反复向进程发送sigint(通过按 Ctrl+C 在大多数贝壳中)。(由Reid Kleckner出资; bpo-8844

优化

增加了一些小的性能增强:

  • python的窥视孔优化器现在可以识别这样的模式 x in {{1, 2, 3}} 作为一组常量中成员资格的测试。优化器重新编译 set 作为一个 frozenset 并存储预建常量。

    既然速度惩罚已经消失,那么使用集合符号编写成员资格测试是可行的。这种风格在语义上清晰,在操作上快速:

    extension = name.rpartition('.')[2]
    if extension in {'xml', 'html', 'xhtml', 'css'}:
        handle(name)
    

    (由Dave Malcolm提供补丁和附加测试; bpo-6690

  • 使用 pickle 模块现在快了几倍。

    (由亚历山大·瓦萨洛蒂、安托万·皮特鲁和unladen燕子队在 bpo-9410bpo-3873

  • 这个 Timsort algorithm 用于 list.sort()sorted() 现在运行速度更快,使用 key function . 以前,列表中的每一个元素都被一个临时对象封装,这个临时对象记住了与每个元素关联的键值。现在,两个键和值数组并行排序。这样可以节省排序封装器消耗的内存,并节省委派比较所浪费的时间。

    (Daniel Stutzbach在 bpo-9915

  • 每当对多个键重复相同的字符串时,JSON解码性能会得到提高,内存消耗也会减少。此外,json编码现在使用c加速,当 sort_keys 参数为真。

    (由Antoine Pitrou在 bpo-7451 雷蒙德·赫廷格和安托万·皮特鲁 bpo-10314

  • 递归锁(使用 threading.RLock() API)现在可以从C实现中获益,它使它们的速度与常规锁一样快,比以前的纯Python实现快10到15倍。

    (安托万·皮特鲁提供; bpo-3001

  • StringLib中的快速搜索算法现在被 split()rsplit()splitlines()replace() 方法对 bytesbytearraystr 物体。同样,算法也被 rfind()rindex()rsplit()rpartition() .

    (弗洛伦西克拉纳在 bpo-7622bpo-7462

  • 整数到字符串的转换现在一次工作两个“数字”,减少了除法和模运算的次数。

    (bpo-6713 作者:加文·博尔顿、马克·狄金森和维克托·斯廷纳。)

还有其他一些小的优化。当一个操作数比另一个操作数大得多时,set differencing现在运行得更快(在 bpo-8685 )这个 array.repeat() 方法的实现速度更快 (bpo-1569291 亚历山大·伯罗波尔斯基)。这个 BaseHTTPRequestHandler 有更有效的缓冲 (bpo-3709 作者:安德鲁·沙夫)。这个 operator.attrgetter() 功能已加快 (bpo-10160 克里斯托斯·乔治奥)。和 ConfigParser 加载多行参数更快 (bpo-7113 作者:Ukasz Langa)。

unicode

python已更新为 Unicode 6.0.0 . 标准的更新增加了2000多个新字符,包括 emoji 对手机很重要的符号。

此外,更新后的标准修改了两个卡纳达字符(u+0cf1,u+0cf2)和一个新的泰鲁数字字符(u+19da)的字符属性,使前者有资格用于标识符,而取消后者的资格。有关详细信息,请参阅 Unicode Character Database Changes .

编解码器

为添加了支持 CP720 阿拉伯语DOS编码 (bpo-1616979

MBCS编码不再忽略错误处理程序参数。在默认的严格模式下,它将引发 UnicodeDecodeError 当它遇到不可编码的字节序列和 UnicodeEncodeError 对于一个不可编码的角色。

MBCS编解码器支持 'strict''ignore' 解码错误处理程序,以及 'strict''replace' 用于编码。

要模拟python3.1 mbcs编码,请选择 'ignore' 解码处理程序和 'replace' 编码处理程序。

在Mac OS X上,python使用 'utf-8' 而不是区域设置编码。

默认情况下, tarfile 使用 'utf-8' 在Windows上编码(而不是 'mbcs''surrogateescape' 所有操作系统上的错误处理程序。

文档

文件继续得到改进。

  • 已将快速链接表添加到长节的顶部,如 内置功能 . 在情况下 itertools 链接附带了作弊表样式的摘要表,以提供概述和内存点动,而无需阅读所有文档。

  • 在某些情况下,纯Python源代码可以作为文档的一个有用附件,因此现在许多模块都提供了到源代码最新版本的快速链接。例如, functools 模块文档顶部有一个快速链接,标记为:

    源代码 Lib/functools.py .

    (由Raymond Hettinger提供;见 rationale

  • 这些文档现在包含更多的示例和秘诀。特别地, re 模块有一个扩展部分, 正则表达式示例 . 同样地, itertools 模块继续更新为新的 Itertools秘诀 .

  • 这个 datetime 模块现在有了纯Python中的辅助实现。未更改任何功能。这只是提供了一个更容易阅读的替代实现。

    (亚历山大·伯罗波尔斯基于年 bpo-9528

  • 未经维护的 Demo 目录已被删除。一些演示已集成到文档中,一些已移动到 Tools/demo 目录和其他目录一起被删除。

    (乔治布兰德尔在 bpo-7962

IDLE

  • “格式”菜单现在有一个选项,可以通过去除尾随空格来清除源文件。

    (由Raymond Hettinger提供; bpo-5150

  • 空闲在MacOSX上现在可以同时使用CarbonAquatk和CocoaAquatk。

    (由凯文·沃尔泽、内德·戴利和罗纳德·奥索伦贡献; bpo-6075

代码库

除了http://svn.python.org上现有的Subversion代码存储库外,现在还有一个 Mercurial 存储库位于https://hg.python.org/。

在3.2版本发布之后,有计划将Mercurial作为主存储库。这个分布式版本控制系统应该使社区成员更容易创建和共享外部变更集。见 PEP 385 有关详细信息。

要学习使用新版本的控制系统,请参见 Quick StartGuide to Mercurial Workflows .

构建和C API更改

对python构建过程和C API的更改包括:

  • 这个 idlepydoc2to3 脚本现在安装时带有版本特定的后缀 make altinstall (bpo-10679

  • 访问Unicode数据库的C函数现在接受并返回整个Unicode范围内的字符,即使是在狭窄的Unicode构建上(py_unicode_tolower、py_unicode_ispecial等)。在python中一个明显的区别是 unicodedata.numeric() 现在返回大代码点的正确值,以及 repr() 可以将更多字符视为可打印字符。

    (由Bupjoe Lee报告,由Amaury Forgot d'Arc修复; bpo-5127

  • 现在,默认情况下,在受支持的编译器(由配置脚本检测)上启用计算goto。通过指定 --without-computed-gotos .

    (安托万·皮特鲁提供; bpo-9203

  • 选择权 --with-wctype-functions 被移除。内置的Unicode数据库现在用于所有函数。

    (由Amaury Forgot d'Arc出资; bpo-9210

  • hash值现在是新类型的值, Py_hash_t ,它被定义为与指针大小相同。以前它们是long类型的,在一些64位操作系统上仍然只有32位的长度。由于这个修复, setdict 现在可以容纳超过 2**32 带有64位指针的构建上的条目(以前,它们可以增长到该大小,但性能会急剧下降)。

    (由Raymond Hettinger提出,Benjamin Peterson实施; bpo-9778

  • 一个新的宏 Py_VA_COPY 复制变量参数列表的状态。相当于C99 va_copy 但在所有的python平台上都可用 (bpo-2443

  • 一个新的C API函数 PySys_SetArgvEx() 允许嵌入式解释器设置 sys.argv 无需修改 sys.path (bpo-5753

  • PyEval_CallObject 现在只在宏窗体中可用。由于向后兼容的原因而保留的函数声明现在被删除——宏是在1997年引入的 (bpo-8276

  • 有一个新功能 PyLong_AsLongLongAndOverflow() 类似于 PyLong_AsLongAndOverflow() .它们都是用来转换 Python 的 int 转换为本机固定宽度类型,同时检测转换不适合的情况 (bpo-7767

  • 这个 PyUnicode_CompareWithASCIIString() 函数现在返回 不等 如果python字符串是 NUL 结束。

  • 有一个新功能 PyErr_NewExceptionWithDoc() 就像是 PyErr_NewException() 但允许指定docstring。这使得C异常具有与纯Python异常相同的自文档功能。 (bpo-7033

  • 当用 --with-valgrind 选项,当在valgrind下运行时,将自动禁用pymalloc分配器。这在Valgrind下运行时提供了改进的内存泄漏检测,同时在其他时间利用pymalloc (bpo-2422

  • 移除 O? 格式从 PyArg_Parse 功能。该格式已不再使用,而且从未被记录在案 (bpo-8837

C-API还有许多其他的小改动。见 Misc/NEWS 完整列表的文件。

此外,还有许多对Mac OS X版本的更新,请参见 Mac/BuildScript/README.txt 详情。对于运行32/64位构建的用户,Mac OS X 10.6上的默认tcl/tk存在已知问题。因此,我们建议安装更新的替代方案,例如 ActiveState Tcl/Tk 8.5.9 。有关更多详细信息,请参阅https://www.python.org/download/mac/tcltk/。

移植到python 3.2

本节列出了前面描述的可能需要更改代码的更改和其他错误修复:

  • 这个 configparser 模块有许多清理。主要的改变是取代旧的 ConfigParser 有长期优先选择的课程 SafeConfigParser . 此外,还有一些较小的不相容性:

    • 内插语法现在验证于 get()set() 操作。在默认的插值方案中,只有两个带百分号的标记有效: %(name)s%% ,后者是一个转义的百分号。

    • 这个 set()add_section() 方法现在验证值是否为实际字符串。以前,不支持的类型可能是无意中引入的。

    • 从单个源复制节或选项现在引发 DuplicateSectionErrorDuplicateOptionError . 以前,重复项会自动覆盖以前的项。

    • 默认情况下,内联注释现在被禁用,因此 ; 字符可以安全地用于值中。

    • 现在可以缩进注释。因此,为了 ;# 要在多行值的行首显示,必须对其进行插值。这样可以防止值中的注释前缀字符被误认为是注释。

    • "" 现在是有效值,不再自动转换为空字符串。对于空字符串,请使用 "option =" 在一条线上。

  • 这个 nntplib 模块被大量修改,这意味着其API通常与3.1 API不兼容。

  • bytearray 对象不能再用作文件名;相反,应将它们转换为 bytes .

  • 这个 array.tostring()array.fromstring() 已重命名为 array.tobytes()array.frombytes() 为了清晰起见。旧名称已被弃用。(见 bpo-8990

  • PyArg_Parse*() 功能:

    • “T”格式已被删除:请改用“S”或“S*”

    • “w”和“w”格式已被删除:请改用“w*”

  • 这个 PyCObject 已删除3.1中弃用的类型。要在Python对象中封装不透明的C指针,请 PyCapsule 应该改为使用API;新类型有一个定义良好的接口来传递类型安全信息,还有一个不太复杂的签名来调用析构函数。

  • 这个 sys.setfilesystemencoding() 功能被删除,因为它的设计有缺陷。

  • 这个 random.seed() 函数和方法现在用sha512散列函数盐字符串种子。访问以前版本的 seed 为了复制python 3.1序列,请设置 版本 参数 1random.seed(s, version=1) .

  • 先前已弃用的 string.maketrans() 为了支持静态方法,已移除函数 bytes.maketrans()bytearray.maketrans() . 此更改解决了关于哪些类型由 string 模块。现在, strbytesbytearray 每个人都有自己的 美孚公司翻译 方法使用适当类型的中间翻译表。

    (由乔治布兰德尔提供; bpo-5675

  • 先前已弃用的 contextlib.nested() 函数已被删除,而不是普通函数 with 可以接受多个上下文管理器的语句。后一种技术更快(因为它是内置的),并且当其中一个上下文管理器引发异常时,它可以更好地完成多个上下文管理器:

    with open('mylog.txt') as infile, open('a.out', 'w') as outfile:
        for line in infile:
            if '<critical>' in line:
                outfile.write(line)
    

    (由Georg Brandl和Mattias Br_ndstr_m提供; appspot issue 53094

  • struct.pack() 现在只允许字节用于 s 字符串包代码。以前,它会接受文本参数,并使用UTF-8将其隐式编码为字节。这是有问题的,因为它对正确的编码做了假设,而且在写入结构的固定长度段时,可变长度编码可能会失败。

    代码如 struct.pack('<6sHHBBB', 'GIF87a', x, y) 应该用重写来使用字节而不是文本, struct.pack('<6sHHBBB', b'GIF87a', x, y) .

    (大卫·比兹利发现,维克多·斯廷纳修复; bpo-10783

  • 这个 xml.etree.ElementTree 现在,类引发一个 xml.etree.ElementTree.ParseError 当分析失败时。以前它提出了一个 xml.parsers.expat.ExpatError .

  • 新的,更长的 str() 浮点数上的值可能会破坏依赖于旧输出格式的doctest。

  • subprocess.Popen ,的默认值 close_fds 现在是 True 在Unix下;在Windows下 True 如果将三个标准流设置为 NoneFalse 否则。以前, close_fds 总是 False 默认情况下,当打开的文件描述符泄漏到子进程中时,会产生难以解决的错误或竞争条件。

  • 已从中删除对旧版HTTP 0.9的支持 urllib.requesthttp.client . 这样的支持仍然存在于服务器端(在 http.server

    (由Antoine Pitrou提供, bpo-10711

  • 超时模式下的SSL套接字现在上升 socket.timeout 当发生超时时,而不是一般的 SSLError .

    (由Antoine Pitrou提供, bpo-10272

  • 误导性功能 PyEval_AcquireLock()PyEval_ReleaseLock() 已被正式否决。线程状态感知API(例如 PyEval_SaveThread()PyEval_RestoreThread() )应该改为使用。

  • 由于安全风险, asyncore.handle_accept() 已被弃用,新函数, asyncore.handle_accepted() ,以替换它。

    (由Giampaolo Rodola在 bpo-6706

  • 由于新 GIL 实施, PyEval_InitThreads() 之前不能调用 Py_Initialize() 不再。