What’s New In Python 3.2

作者:Raymond Hettinger

本文解释了与3.1相比,Python 3.2中的新功能。它集中在几个亮点,并举几个例子。有关详细信息,请参阅Misc / NEWS文件。

也可以看看

PEP 392 - Python 3.2发布计划

PEP 384: Defining a Stable ABI

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

使用Python 3.2,一个替代方法变得可用:扩展模块限制自己到一个有限的API(通过定义Py_LIMITED_API)不能使用许多内部,但是被限制到一组API函数被承诺在几个版本是稳定的。因此,在该模式下为3.2构建的扩展模块也将与3.3,3.4等工作。使用内存结构细节的扩展模块仍然可以构建,但需要为每个功能部件发布重新编译。

也可以看看

PEP 384 - 定义稳定ABI
PEP由Martin vonLöwis写。

PEP 389: Argparse Command Line Parsing Module

引入了用于命令行解析的新模块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由Steven Bethard编写。

Upgrading optparse code以了解有关与optparse的差异的详细信息。

PEP 391: Dictionary Based Configuration for Logging

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 - 日志记录的基于字典的配置
PEP由Vinay Sajip编写。

PEP 3148: The concurrent.futures module

创建和管理并发的代码正在新的顶级命名空间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由Brian Quinlan编写。

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

Code for computing prime numbers in parallel,演示ProcessPoolExecutor的示例。

PEP 3147: PYC Repository Directories

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

“pyc fights”的问题变得更加明显,因为Linux发行版随着多个版本的Python一起变得普遍。这些冲突也出现在CPython的替代品,如Unladen Swallow。

为了解决这个问题,Python的导入机制已经扩展到为每个解释器使用不同的文件名。代替Python 3.2和Python 3.3和Unladen Swallow每个竞争一个名为“mymodule.pyc”的文件,他们现在将寻找“mymodule.cpython-32.pyc”,“mymodule.cpython-33.pyc”和“mymodule .unladen10.pyc“。为了防止所有这些新文件混乱的源目录,pyc文件现在收集在存储在package目录下的“__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模块已更新,以反映新的命名约定和目标目录。compileall的命令行调用具有新选项:-i用于指定要编译的文件和目录的列表,-b其导致字节码文件写入其旧位置,而不是__ pycache __

  • importlib.abc模块已更新为新的abstract base classes,用于加载字节码文件。过时的ABC,PyLoaderPyPycLoader已被弃用(关于如何保留Python 3.1兼容的说明包括在文档中)。

也可以看看

PEP 3147 - PYC存储库目录
PEF写的巴里华沙。

PEP 3149: ABI Version Tagged .so Files

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

通用目录是“pyshared”,通过标识Python实现(如CPython,PyPy,Jython等)使文件名独立。),主版本号和次版本号以及可选的构建标志(例如调试时使用“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文件
PEF写的巴里华沙。

PEP 3333: Python Web Server Gateway Interface v1.0.1

此信息PEP阐明了字节/文本问题如何由WSGI协议处理。挑战是Python 3中的字符串处理最方便的处理与str类型,即使HTTP协议本身面向字节。

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

本地字符串始终为类型str,但限于U + 0000U + 00FF它们可以使用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()函数和environ必须使用本机字符串。两者不能混合。

对于编写CGI到WSGI路径或其他CGI式协议的服务器实施者,用户必须能够使用本地字符串访问环境,即使底层平台可能有不同的约定。To bridge this gap, the wsgiref module has a new function, wsgiref.handlers.read_environ() for transcoding CGI variables from os.environ into native strings and returning a new dictionary.

也可以看看

PEP 3333 - Python Web Server网关接口v1.0.1
PEP由Phillip Eby编写。

Other Language Changes

核心Python语言的一些较小的更改是:

  • format()str.format()的字符串格式已获得格式字符的新功能。以前,对于二进制,八进制或十六进制的整数,它导致输出分别以'0b','0o'或'0x'作为前缀。现在它也可以处理浮点数,复数和十进制,导致输出总是有一个小数点,即使没有数字跟在它后面。

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

    (由Mark Dickinson建议,由Eric Smith在issue 7094中实施)。

  • 还有一个新的str.format_map()方法通过接受任意mapping对象来扩展现有str.format()This new method makes it possible to use string formatting with any of Python’s many dictionary-like objects such as defaultdict, Shelf, ConfigParser, or dbm. 它也可用于自定义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>'
    
(Suggested by Raymond Hettinger and implemented by Eric Smith in issue 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在issue 1772833提供)。

  • hasattr()函数通过调用getattr()工作,并检测是否引发异常。这种技术允许它检测由类字典中不存在的__getattr__()__getattribute__()动态创建的方法。以前,hasattr会捕获任何异常,可能会掩盖真正的错误。现在,hasattr已收紧,只捕获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
    

    (由Yury Selivanov发现,由Benjamin Peterson修订; 问题9666。)

  • 浮点数或复数的str()现在与其repr()相同。以前,str()形式更短,但只是造成混乱,现在不再需要,默认显示最短的可能repr()

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

    (由Mark Dickinson提议和实施; 第9337期。)

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

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

    (由Antoine Pitrou添加; 问题9757。)

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

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

    现在允许。请记住,except子句的目标已清除,因此此代码与Python 2.6一起使用,使用Python 3.1引发了一个SyntaxError,现在可以重新运行:

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

    (请参阅issue 4617。)

  • 内部structsequence工具现在创建元组的子类。这意味着像os.stat()time.gmtime()sys.version_info返回的C结构现在的工作方式类似于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 Arahesis提出,由Benjamin Peterson在问题8413中实施)。

  • 现在可以使用 PYTHONWARNINGS环境变量更容易控制警告,作为在命令行中使用-W的替代方法:

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

    (由Barry Warsaw提出,由Philip Jenvey在问题7301中实施。)

  • 添加了新的警告类别ResourceWarning当检测到与资源消耗或清除的潜在问题时,它被发射。默认情况下,它在正常版本构建中被禁止,但可以通过warnings模块或命令行提供的方式启用。

    如果gc.garbage列表不为空,并且如果设置gc.DEBUG_UNCOLLECTABLE,则在解释器关闭时发出ResourceWarning对象被打印。这意味着让程序员知道他们的代码包含对象最终化问题。

    file object被销毁而未显式关闭时,也会发出ResourceWarning虽然这种对象的释放器确保它关闭底层操作系统资源(通常是文件描述器),但释放对象的延迟会产生各种问题,尤其是在Windows下。以下是从命令行启用警告的示例:

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

    (由Antoine Pitrou和Georg Brandl在问题10093问题477863中添加)。

  • range对象现在支持索引计数方法。这是使更多对象完全实现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在问题9213中由Alexander Belopolsky在问题2690提供,以及Nick Coghlan在问题10889中提供)

  • 来自Py2.x的callable()内置函数已复活。它提供了一个简洁,可读的替代方法,在的表达式中使用abstract base class isinstance(x, 容器.Callable) / t2>:

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

    (请参阅问题10518。)

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

(Required extensive work by Victor Stinner in issue 9425.)

New, Improved, and Deprecated Modules

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

Python 3.2的最大新闻是,email包,mailbox模块和nntplib模块现在可以与Python / 3。第一次,正确处理具有混合编码的消息。

在整个标准库中,对编码和文本对字节的问题更加注意。特别是,与操作系统的交互现在可以更好地使用Windows MBCS编码,区域设置感知编码或UTF-8交换非ASCII数据。

另一个重要的成功是为SSL连接和安全证书添加了更好的支持。

此外,更多的类现在实现context manager,以支持使用with语句进行方便可靠的资源清理。

email

Python 3中的email包的可用性大部分是由R. David Murray的广泛努力所固定的。问题是,电子邮件通常以bytes而不是str文本的形式读取和存储,并且它们可能在单个电子邮件中包含多个编码。因此,电子邮件包必须扩展为以字节格式解析和生成电子邮件。

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

  • 给定模型输入的字节,get_payload()将默认使用8位来解码具有内容传输编码的消息体在MIME头中指定的字符集,并返回结果字符串。

  • 给定模型输入的字节,Generator将将具有8位内容传输编码的消息体转换为 7bit Content-Transfer-Encoding

    具有未编码的非ASCII字节的标题被认为是使用unknown-8bit字符集编码的 RFC 2047

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

  • smtplib SMTP类现在接受sendmail()方法的msg参数的字节字符串,新方法,send_message()接受Message对象,并且可以选择从from_addr目的。

(由R. David Murray提出并实施,问题4661问题10321。)

elementtree

xml.etree.ElementTree包及其xml.etree.cElementTree对应版本已更新到版本1.3。

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

两种方法已被弃用:

  • xml.etree.ElementTree.getchildren()使用list(elem)
  • xml.etree.ElementTree.getiterator()改用Element.iter

有关更新的详细信息,请参阅Fredrik Lundh网站上的ElementsTree介绍

(由Florent Xicluna和Fredrik Lundh提供,issue 6472。)

functools

  • 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的设计思想;参见配方498245配方577479,和发行10593。)

  • functools.wraps()装饰器现在添加指向原始可调用函数的__wrapped__属性。这允许包装函数自我检查。如果定义,它还会复制__annotations__现在它也优雅地跳过缺少的属性,如__doc__,这可能没有为包装的可调用对象定义。

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

    >>> get_phone_number = get_phone_number.__wrapped__    # uncached function
    

    (由Nick Coghlan和Terrence Cole发行; 发行9567发行3445发行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装饰器,将自动填充剩余的比较方法。

    (由Raymond Hettinger提供)

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

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

    有关排序示例和简要排序教程,请参阅排序方法教程。

    (由Raymond Hettinger提供)

itertools

  • itertools模块在APL的扫描操作符和Numpy的accumulate函数上建立了一个新的accumulate()

    >>> 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

  • collections.Counter类现在具有两种形式的就地减法,用于饱和减法的现有 - =操作符和新subtract()方法进行常规减法。前者适用于只有正计数的多集,后者更适合允许负计数的用例:

    >>> 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

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)

在本示例中,障碍强制执行更鲁棒的规则。如果一些选举地点在午夜之前没有完成,则障碍超时和选票被密封并且被放置在队列中以便稍后处理。

有关如何在并行计算中使用障碍的更多示例,请参见障碍同步模式此外,在“信号量的小书”第3.6节中有一个简单但彻底的解释。

(由KristjánValurJónsson提供,由Jeffrey Yasskin在问题8777提供的API审核)。

datetime and time

  • datetime模块具有通过返回固定的UTC偏移和时区名称实现tzinfo接口的新类型timezone这使得更容易创建时区感知datetime对象:

    >>> 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格式的POSIX规则猜测世纪。

    从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'
    

    现在有几个函数已明显扩展日期范围。When time.accept2dyear is false, the time.asctime() function will accept any year that fits in a C int, while the time.mktime() and time.strftime() functions will accept the full range supported by the corresponding operating system functions.

(Contributed by Alexander Belopolsky and Victor Stinner in issue 1289118, issue 5094, issue 6641, issue 2706, issue 1777412, issue 8013, and issue 10827.)

math

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

isfinite()函数提供了一种可靠且快速的方式来检测特殊值。对于常规数字返回True,对于NanInfinity返回False

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

对于x的小值,expm1()函数计算e**x-1,而不会导致通常伴随减法几乎相等数量:

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

erf()函数计算概率积分或高斯误差函数互补误差函数erfc()1 - erf(x) t3 >:

>>> 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_function因为函数与阶乘相关,所以即使对于小的值x它也变大,因此还存在用于计算伽马函数的自然对数的lgamma()

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

(供稿人:Mark Dickinson。)

abc

abc模块现在支持abstractclassmethod()abstractstaticmethod()

这些工具可以定义需要实现特定classmethod()staticmethod()abstract base class

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

(由Daniel Urban提交的修补程序; 问题5867。)

io

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提供,载于issue 5506。)

reprlib

当为自定义容器编写__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在issue 9826issue 9840中提供。)

logging

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

日志文档已通过basic tutorialadvanced tutorialcookbook增强。这些文档是了解日志记录的最快方式。

logging.basicConfig()设置函数获得了样式参数,以支持三种不同类型的字符串格式化。对于传统的%格式,它默认为“%”,对于新的str.format()样式可以设置为“{”,对于shell样式格式可以设置为“$”由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")

If no configuration is set-up before a logging event occurs, there is now a default configuration using a StreamHandler directed to sys.stderr for events of WARNING level or higher. 以前,在配置设置之前发生的事件将引发异常或者根据logging.raiseExceptions的值静默地丢弃事件。新的默认处理程序存储在logging.lastResort中。

过滤器的使用已经简化。除了创建Filter对象,谓词可以是返回TrueFalse的任何Python可调用对象。

还有一些其他的改进,增加了灵活性和简化配置。有关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在issue 5975中建议的新方言,以及Ed Abraham在问题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: {}'.format(name))
    yield
    logging.info('Exiting: {}'.format(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上下文管理器没有干净的方式来返回用于封闭语句的主体中的日志实例。

(Contributed by Michael Foord in issue 9110。)

decimal and fractions

Mark Dickinson制定了一个优雅和高效的方案,用于确保不同的数字数据类型在实际值相等(issue 8188)时具有相同的哈希值:

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

一些哈希细节通过新属性sys.hash_info来公开,该属性描述散列值的位宽度,素模数,无穷大的散列值nan,以及用于数字虚数部分的乘数:

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

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

Similar changes were made to fractions.Fraction so that the from_float() and from_decimal() methods are no longer needed (issue 8294):

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

decimal模块的另一个有用的更改是Context.clamp属性现在是公共的。这在创建与IEEE 754中指定的十进制交换格式(参见issue 8540)相对应的上下文时很有用。

(供稿人:Mark Dickinson和Raymond Hettinger。)

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)

(由issue 4972中的TarekZiadé和GiampaoloRodolà提供,以及Georg Brandl在问题8046问题1286中提供)

FTP_TLS类现在接受上下文参数,它是一个ssl.SSLContext对象,允许将SSL配置选项,证书和私钥绑定到单个(可能长寿)结构。

(由GiampaoloRodolà提供; 发行8806。)

popen

os.popen()subprocess.Popen()函数现在支持with语句自动关闭文件描述器。

(由Antoine Pitrou和Brian Curtin在问题7461问题10554提供)。

select

select模块现在暴露一个新的常量属性PIPE_BUF,它提供了最小字节数,保证当select.select()

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

(在Unix系统上可用。Patch bySébastienSabléin issue 9862

gzip and 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'

(Contributed by Anand B. Pillai in issue 3488; and by Antoine Pitrou, Nir Aides and Brian Curtin in issue 9962, issue 1675951, issue 7471 and issue 2846.)

此外,zipfile.ZipExtFile类在内部重做以表示存储在存档内的文件。新的实现显着更快,可以包装在io.BufferedReader对象中,以获得更多的加速。它还解决了读取readline的交错调用给出错误的结果的问题。

(Nir Aides在issue 7610中提交的补丁)。

tarfile

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

新的过滤器选项替换了旧的,不太灵活的排除参数,现在已被弃用。如果指定,可选的过滤器参数需要是keyword argument用户提供的过滤器函数接受一个TarInfo对象并返回一个更新的TarInfo对象,或者如果想要排除该文件,函数可以返回/ t6>:

>>> 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

(由TarekZiadé提出,由LarsGustäbel在问题6856中实施。)

hashlib

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

>>> 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在issue 7418中提供)。

ast

ast模块有一个美妙的通用工具,用于使用Python字面值语法安全地评估表达式字符串。ast.literal_eval()函数可作为内置eval()函数的安全替代方案,容易被滥用。Python 3.2将bytesset字面值添加到支持的类型列表:字符串,字节,数字,元组,列表,dicts,集合,布尔和无。

>>> 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

不同的操作系统使用文件名和环境变量的各种编码。os模块提供了用于编码和解码文件名的两个新函数:fsencode()fsdecode()

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

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

要直接访问编码环境变量(如果可用),请使用新的os.getenvb()函数或使用os.environb这是os.environ

(由Victor Stinner撰稿)

shutil

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

  • ignore_dangling_symlinks:当symlinks=False时,函数复制符号链接指向的文件,而不是符号链接本身。如果文件不存在,此选项将忽略引发的错误。
  • copy_function:是一个可调用,将用于复制文件。默认情况下使用shutil.copy2()

(由TarekZiadé提供)

此外,shutil模块现在支持zipfiles,未压缩tarfiles,gzipped tarfiles和bzipped tarfiles的archiving operations还有用于注册其他归档文件格式(例如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'
... )

(由TarekZiadé提供)

sqlite3

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

(由R.David Murray和Shashwat Anand提供; 问题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添加; issue 8524。)
  • socket.create_connection()现在支持上下文管理协议无条件地使用socket.error异常并在完成后关闭套接字。(由GiampaoloRodolà提供; 第9794期。)

ssl

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

  • 新类别SSLContext用作持久SSL数据的容器,例如协议设置,证书,私钥和各种其他选项。它包括用于从SSL上下文创建SSL套接字的wrap_socket()
  • 新功能ssl.match_hostname()通过实施HTTPS的规则支持对较高级别协议的服务器身份验证(从 RFC 2818 ),其也适用于其他协议。
  • ssl.wrap_socket()构造函数现在采用密码参数。密码字符串列出了使用OpenSSL文档中描述的格式的允许的加密算法。
  • 当链接到最新版本的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在问题8850问题1589发出8322问题56394870发出8484发出8321。)

nntp

nntplib模块具有更好的字节和文本语义的改进实现以及更实用的API。这些改进打破了与Python 3.1中的nntplib版本的兼容性,这本身就是部分功能失调。

还添加了通过隐式(使用nntplib.NNTP_SSL)和显式(使用nntplib.NNTP.starttls())TLS的安全连接。

(由Antoine Pitrou在issue 9360和Andrew Vant在问题1926提供)。

certificates

http.client.HTTPSConnectionurllib.request.HTTPSHandlerurllib.request.urlopen()现在接受可选参数,以允许进行服务器证书检查针对一组证书颁发机构,根据HTTPS的公共使用建议。

(由Antoine Pitrou添加,问题9003。)

imaplib

通过新的imaplib.IMAP4.starttls方法添加了对标准IMAP4连接的显式TLS支持。

(由Lorenzo M. Catucci和Antoine Pitrou提供,issue 4471。)

http.client

http.client模块中有一些小的API改进。不再支持旧式HTTP 0.9简单响应,并且在所有类中不推荐使用strict参数。

HTTPConnectionHTTPSConnection类现在具有用于(主机,端口)元组的source_address参数,指示从何处创建HTTP连接。

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

连接对象上的request()方法允许可选的正文参数,以便可以使用file object来提供请求的内容。方便地,主体参数现在也接受iterable对象,只要它包括显式Content-Length头。这个扩展接口比以前更灵活。

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

为了匹配http.server的行为,HTTP客户端库现在还使用ISO-8859-1(拉丁语-1)编码对头进行编码。它已经对传入头进行了操作,因此现在的流入和流出的行为是一致的。(参见Armin Ronacher在问题10980中的工作。)

unittest

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

  • 命令行调用python -m unittest现在可以接受文件路径而不是模块名称(issue 10620)。新的测试发现可以在包中找到测试,找到可从顶级目录导入的任何测试。可以使用-t选项指定顶级目录,使用-p匹配文件的模式和使用-s

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

    (由Michael Foord提供。)

  • 在交互式提示下的实验现在更容易了,因为现在可以不使用参数实例化unittest.case.TestCase类:

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

    (由Michael Foord提供。)

  • unittest模块有两个新方法assertWarns()assertWarnsRegex(),用于验证给定的警告类型是否由测试代码:

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

    (由Antoine Pitrou提供,issue 9754。)

    另一个新方法,assertCountEqual()用于比较两个迭代,以确定它们的元素计数是否相等(无论相同的元素是否以相同的出现次数存在,而不管顺序如何):

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

    (由Raymond Hettinger提供)

  • unittest模块的一个主要特性是在测试失败时产生有意义的诊断。如果可能,故障将与输出的diff一起记录。这对分析失败的测试运行的日志文件特别有用。然而,由于diffs有时可能很大,有一个新的maxDiff属性,设置显示的差异的最大长度。

  • 此外,模块中的方法名称已经过多次清理。

    For example, assertRegex() is the new name for assertRegexpMatches() which was misnamed because the test uses re.search(), not re.match(). 使用正则表达式的其他方法现在使用短语“Regex”优先于“Regexp”命名 - 这匹配在其他unittest实现中使用的名称,匹配Python的旧名称为re模块,并且它明确的骆驼壳。

    (由Raymond Hettinger提供,由Ezio Melotti执行)

  • 为了提高一致性,一些长期使用的方法别名已被弃用,以支持首选名称:

    Old Name Preferred Name
    assert_() assertTrue()
    assertEquals() assertEqual()
    assertNotEquals() assertNotEqual()
    assertAlmostEquals() assertAlmostEqual()
    assertNotAlmostEquals() assertNotAlmostEqual()

    同样,Python 3.1中不推荐使用的TestCase.fail*方法也将在Python 3.3中删除。另请参阅unittest文档中的Deprecated aliases部分。

    (由Ezio Melotti提供; 发行9424。)

  • assertDictContainsSubset()方法已被弃用,因为它使用错误顺序的参数执行错误。This created hard-to-debug optical illusions where tests like TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1}) would fail.

    (由Raymond Hettinger提供)

random

random模块中的整数方法现在可以更好地生成均匀分布。以前,他们用int(n*random())计算选择,当n不是2的幂时,其具有轻微的偏差。Now, multiple selections are made from a range up to the next power of two and a selection is kept only when it falls within the range 0 <= x < n. The functions and methods affected are randrange(), randint(), choice(), shuffle() and sample().

(由Raymond Hettinger提供; issue 9025。)

poplib

POP3_SSL类现在接受上下文参数,它是一个ssl.SSLContext对象,允许将SSL配置选项,证书和私钥捆绑到单个潜在的长寿)结构。

(由GiampaoloRodolà提供; 发行8807。)

asyncore

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

(由GiampaoloRodolà提供; 问题6706。)

tempfile

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

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

(由Neil Schemenauer和Nick Coghlan提供; 问题5178。)

inspect

  • 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提供,issue 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>
    
(Contributed by Michael Foord.)

pydoc

pydoc模块现在提供了一个经过大幅改进的Web服务器接口,以及一个新的命令行选项-b,可自动打开浏览器窗口以显示该服务器:

$ pydoc3.2 -b

(由Ron Adam提供; issue 2001。)

dis

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在issue 9147中提供。)

dbm

All database modules now support the get() and setdefault() methods.

(由Ray Allen在issue 9523中提供)。

ctypes

新类型ctypes.c_ssize_t表示C ssize_t数据类型。

site

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

(由TarekZiadé在issue 6693中提供。)

sysconfig

新的sysconfig模块可以直接发现不同平台和安装中的安装路径和配置变量。

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

它还提供对与distutils使用的七个命名方案之一相对应的路径和变量的访问。Those include posix_prefix, posix_home, posix_user, nt, nt_user, os2, os2_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"

(从TarekZiadé的Distutils中移除)。

pdb

pdb调试器模块获得了许多可用性改进:

  • pdb.py现在有一个-c选项,可执行.pdbrc脚本文件中给出的命令。
  • .pdbrc脚本文件可以包含继续调试的continuenext命令。
  • Pdb类构造函数现在接受一个nosigint参数。
  • 新命令:l(list)ll(long list)source用于列出源代码。
  • 新命令:displayundisplay,用于显示或隐藏表达式的值(如果已更改)。
  • 新命令:interact用于启动包含当前范围中找到的全局和局部名称的交互式解释器。
  • 断点可以通过断点号清除。

(供稿:Georg Brandl,Antonio Cuni和Ilya Sandler。)

configparser

修改了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函数指定回退值,或直接从字典和字符串中读取。

(ŁukaszLanga提供的所有更改。)

urllib.parse

urllib.parse模块进行了一些可用性改进。

urlparse()函数现在支持 RFC 2732中描述的IPv6地址:

>>> 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()函数现在更加灵活,接受查询参数的字符串或字节类型。如果是字符串,则将安全编码错误参数发送到quote_plus()

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

Parsing ASCII Encoded Bytes中所述,所有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在问题2987 t>>,问题5468问题9873

mailbox

由于R. David Murray的一致努力,mailbox模块已针对Python 3.2修复。挑战是邮箱最初设计有文本界面,但电子邮件最好用bytes表示,因为邮件的各个部分可能有不同的编码。

该解决方案利用email包的二进制支持来解析任意电子邮件。此外,该解决方案需要多个API更改。

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

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

还支持二进制输出。get_file()方法现在以二进制模式(其中用于将文件不正确地设置为文本模式)返回一个文件。还有一个新的get_bytes()方法,返回与给定对应的消息的bytes表示。

仍然可以使用旧API的get_string()方法获取非二进制输出,但该方法不是非常有用。相反,最好从Message对象中提取消息,或者从二进制输入加载消息。

(由R.David Murray提供,由Steffen Daode Nurpmeso的努力和Victor Stinner在问题9124中的初始补丁)。

turtledemo

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

$ python -m turtledemo

(由Alexander Belopolsky在问题10199中从演示目录移动。)

Multi-threading

  • 用于串行执行并行运行的Python线程(通常称为GILGlobal Interpreter Lock)的机制已被重写。其中的目标是更可预测的切换间隔和减少由于锁竞争和随后的系统调用的数量的开销。允许线程切换的“检查间隔”的概念已经被放弃并且被以秒表示的绝对持续时间替代。此参数可通过sys.setswitchinterval()调整。它目前默认为5毫秒。

    有关实现的其他详细信息可以从python-dev邮件列表消息中读取(但是,此消息中公开的“优先级请求”尚未保留)。

    (由Antoine Pitrou提供)

  • 常规和递归锁现在接受对其acquire()方法的可选超时参数。(由Antoine Pitrou提供; issue 7316。)

  • 类似地,threading.Semaphore.acquire()也获得了超时参数。(由Torsten Landschoff提供; 问题850728。)

  • 定期和递归锁定获取现在可以通过使用Pthreads的平台上的信号中断。这意味着,通过重复向进程发送SIGINT(按大多数shell中的Ctrl+C),可以成功地杀死获取锁时死锁的Python程序。(由Reid Kleckner提供; 问题8844。)

Optimizations

增加了许多小的性能增强:

  • Python的窥视孔优化器现在可以识别x {1, 2, 作为对一组常数的成员资格的测试。优化程序将set重写为frozenset并存储预构建的常量。

    现在速度惩罚已经消失了,使用set-notation开始编写成员资格测试是切实可行的。这种风格在语义上清晰和操作快:

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

    (由Dave Malcolm提供的补丁和附加测试; 问题6690)。

  • 使用pickle模块对数据进行串行化和反序列化现在的速度提高了几倍。

    (Contributed by Alexandre Vassalotti,Antoine Pitrou and the Unladen Swallow team in issue 9410 and issue 3873

  • list.sort()sorted()中使用的Timsort算法现在运行速度更快,使用key function以前,列表的每个元素都包含一个临时对象,该对象记住与每个元素相关联的键值。现在,两个键和值的数组并行排序。这节省了排序包装器消耗的内存,并且节省了委托比较所花的时间。

    (补丁:Daniel Stutzbach在第9915期。)

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

    (由Antoine Pitrou在问题7451和Raymond Hettinger和Antoine Pitrou在问题10314中提供)。

  • 递归锁(使用threading.RLock() API创建)现在受益于C实现,它使得它们与常规锁一样快,并且比之前的纯Python实现快10到15倍。

    (由Antoine Pitrou提供; 问题3001。)

  • The fast-search algorithm in stringlib is now used by the split(), rsplit(), splitlines() and replace() methods on bytes, bytearray and str objects. 同样,该算法也由rfind()rindex()rsplit()rpartition()

    (Plot by Florent Xicluna in issue 7622issue 7462)。

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

    (Gawain Bolton,Mark Dickinson和Victor Stinner的issue 6713)。

还有其他一些次要的优化。当一个操作数远大于另一个操作数(由问题8685中的Andress Bennetts修补)时,集合差分运行速度更快。array.repeat()方法具有更快的实现(问题1569291由Alexander Belopolsky)。BaseHTTPRequestHandler具有更高效的缓冲(Andrew Schaaf的发布3709)。operator.attrgetter()函数已加速(Christos Georgiou发布的问题10160)。而且ConfigParser加载多行参数的速度要快一些(问题7113由ŁukaszLanga)。

Unicode

Python已更新为Unicode 6.0.0对标准的更新添加了超过2000个新字符,包括对移动电话很重要的表情符号符号。

此外,更新的标准更改了两个Kannada字符(U + 0CF1,U + 0CF2)和一个新Tai Lue数字字符(U + 19DA)的字符属性,使得前者有资格在标识符中使用,而取消其标识符的资格。有关详细信息,请参阅Unicode字符数据库更改

Codecs

已为cp720阿拉伯语DOS编码(问题1616979)添加了支持。

MBCS编码不再忽略错误处理程序参数。在默认的严格模式下,当遇到不可解码的字节序列和UnicodeEncodeError时,它会引发UnicodeDecodeError

MBCS编解码器支持'strict''ignore'错误处理程序进行解码,'strict''replace'

要模拟Python3.1 MBCS编码,请选择用于解码的'ignore'处理程序和用于编码的'replace'处理程序。

在Mac OS X上,Python使用'utf-8'解码命令行参数,而不是语言环境编码。

By default, tarfile uses 'utf-8' encoding on Windows (instead of 'mbcs') and the 'surrogateescape' error handler on all operating systems.

Documentation

文档继续改进。

  • 快速链接表已添加到诸如Built-in Functions等冗长部分的顶部。itertools的情况下,链接附有cheatsheet样式摘要表,以提供概览和内存缓动,而无需读取所有文档。

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

    Source code Lib/functools.py.

    (由Raymond Hettinger提供;参见理由。)

  • 文档现在包含更多的示例和食谱。特别地,re模块具有广泛的部分,Regular Expression Examples同样,itertools模块继续使用新的Itertools Recipes进行更新。

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

    (由Alexander Belopolsky提供,载于issue 9528。)

  • 未维护的Demo目录已删除。一些演示已集成到文档中,有些已移至Tools/demo目录,其他演示已全部删除。

    (由Georg Brandl在issue 7962中提供。)

IDLE

  • 格式菜单现在有一个选项,通过删除尾部空白来清理源文件。

    (由Raymond Hettinger提供; 问题5150。)

  • Mac OS X上的IDLE现在与Carbon AquaTk和Cocoa AquaTk一起使用。

    (由Kevin Walzer,Ned Deily和Ronald Oussoren提供; 问题6075。)

Code Repository

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

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

要了解如何使用新版本控制系统,请参阅Joel Spolsky的教程Mercurial工作流指南

Build and C API Changes

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

  • The idle, pydoc and 2to3 scripts are now installed with a version-specific suffix on make altinstall (issue 10679).

  • 访问Unicode数据库的C函数现在接受和返回来自完整的Unicode范围的字符,即使在狭窄的unicode构建(Py_UNICODE_TOLOWER,Py_UNICODE_ISDECIMAL和其他)。Python中可见的区别是,unicodedata.numeric()现在返回大代码点的正确值,而repr()可能会将更多字符视为可打印。

    (由Bupjoe Lee报告并由Amaury Forgeot D'Arc修订; 问题5127。)

  • 默认情况下,计算的gotos在支持的编译器上启用(由配置脚本检测)。仍然可以通过指定--without-computed-gotos选择性禁用它们。

    (由Antoine Pitrou提供; 问题9203。)

  • 已删除选项--with-wctype-functions内建unicode数据库现在用于所有功能。

    (由Amaury Forgeot D'Arc提供; 发行9210。)

  • 哈希值现在是一个新类型的值,Py_hash_t,它被定义为与指针相同的大小。以前,它们是long类型的,在一些64位操作系统上仍然只有32位长。作为此修复的结果,setdict现在可以保存多于2**32条目在构建与64位指针(以前,它们可以增长到这种大小,但它们的性能急剧下降)。

    (由Raymond Hettinger提出并由Benjamin Peterson执行; 问题9778。)

  • 新宏Py_VA_COPY复制变量参数列表的状态。它等同于C99 va_copy,但在所有Python平台(问题2443)上可用。

  • A new C API function PySys_SetArgvEx() allows an embedded interpreter to set sys.argv without also modifying sys.path (issue 5753).

  • PyEval_CallObject现在只有宏形式可用。出于向后兼容性原因保留的函数声明现在已删除 - 宏在1997年引入(issue 8276)。

  • 有一个类似于PyLong_AsLongAndOverflow()的新函数PyLong_AsLongLongAndOverflow()它们都用于将Python int转换为本机固定宽度类型,同时提供对转换不适合的情况的检测(发出7767)。

  • 如果Python字符串NUL已终止,则PyUnicode_CompareWithASCIIString()函数现在返回不等于

  • 有一个新的函数PyErr_NewExceptionWithDoc()就像PyErr_NewException(),但允许指定一个docstring。这使得C异常具有与它们的纯Python对等体相同的自记录能力(issue 7033)。

  • 当使用--with-valgrind选项编译时,在Valgrind下运行时,pymalloc分配器将自动禁用。这在Valgrind下运行时提高了内存泄漏检测,同时在其他时间利用pymalloc(issue 2422)。

  • 已移除O?格式从PyArg_Parse函数。格式不再使用,并且从未记录(issue 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/

Porting to Python 3.2

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

  • configparser模块具有多个清除。主要更改是使用长期的首选备用SafeConfigParser替换旧的ConfigParser类。另外还有一些较小的不兼容性:

    • 内插语法现在在get()set()操作上有效。在默认插值方案中,只有具有百分号的两个标记有效:%(name)s%%,后者是转义的百分号。
    • set()add_section()方法现在验证值是否为实际字符串。以前,可能会无意中引入不受支持的类型。
    • 来自单个来源的重复版块或选项现在引发DuplicateSectionErrorDuplicateOptionError以前,重复项将静默覆盖以前的条目。
    • 内联注释默认情况下已禁用,因此现在可以在值中安全使用字符。
    • 现在的注释可以缩进。因此,对于出现在多行值中行的开始处,必须对其进行插值。这会使值中的注释前缀字符被误认为注释。
    • ""现在是一个有效的值,不再自动转换为空字符串。对于空字符串,请在一行中使用“选项 =”
  • nntplib模块被广泛修订,意味着其API通常与3.1 API不兼容。

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

  • array.tostring()array.fromstring()已重命名为array.tobytes()array.frombytes()旧名称已被弃用。(请参阅问题8990。)

  • PyArg_Parse*()函数:

    • “t#”格式已删除:改用“s#”或“s *”
    • “w”和“w#”格式已删除:改用“w *”
  • 已在3.1中弃用的PyCObject类型已删除。要在Python对象中包装不透明C指针,应使用PyCapsule API;新类型具有用于传递打字安全信息和用于调用析构函数的较不复杂的声明的明确定义的接口。

  • sys.setfilesystemencoding()函数已删除,因为它有一个有缺陷的设计。

  • random.seed()函数和方法现在使用sha512散列函数来减少字符串种子。要访问以前版本的种子以重现Python 3.1序列,请将版本参数设置为1random .seed(s, version = 1)

  • 先前已弃用的string.maketrans()函数已被删除,以支持静态方法bytes.maketrans()bytearray.maketrans()此更改解决了string模块支持哪些类型的混乱。现在,strbytesbytearray每个都有自己的maketranstranslate具有适当类型的中间转换表的方法。

    (供稿:Georg Brandl; issue 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和MattiasBrändström提供; appspot问题53094。)

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

    Code such as struct.pack('<6sHHBBB', 'GIF87a', x, y) should be rewritten with to use bytes instead of text, struct.pack('<6sHHBBB', b'GIF87a', x, y).

    (由David Beazley发现,由Victor Stinner修订; 发行10783。)

  • 当解析失败时,xml.etree.ElementTree类现在引发xml.etree.ElementTree.ParseError之前,它引发了一个xml.parsers.expat.ExpatError

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

  • subprocess.Popen中,close_fds的默认值现在为True在Windows下,如果三个标准流设置为NoneFalse则为True以前,默认情况下,close_fds始终为False,这在打开文件描述器会泄漏到子进程中时很难解决错误或竞争条件。

  • 已从urllib.requesthttp.client中删除了对旧版HTTP 0.9的支持。此类支持仍存在于服务器端(在http.server中)。

    (由Antoine Pitrou提供,问题10711。)

  • 超时模式下的SSL套接字现在引发socket.timeout,而不是通用的SSLError

    (由Antoine Pitrou提供,issue 10272。)

  • 误导函数PyEval_AcquireLock()PyEval_ReleaseLock()已被正式弃用。应该使用线程状态感知API(例如PyEval_SaveThread()PyEval_RestoreThread())。

  • 由于安全风险,asyncore.handle_accept()已被弃用,并添加了一个新函数asyncore.handle_accepted()来替换它。

    (由Giampaolo Rodola在问题6706中提供。)

  • 由于新的GIL实现,PyEval_InitThreads()不能在Py_Initialize()之前调用。