Python 2.7 的新增Function

  • Author

    • 上午。库奇林(amk 在 amk.ca)

本文介绍了 Python 2.7 中的新Function。 Python 2.7 于 2010 年 7 月 3 日发布。

浮点数和Decimal类的数值处理都已pass许多方式得到改进。标准库有一些有用的补充,例如大大增强的unittest模块,用于解析命令行选项的argparse模块,collections模块中方便的OrderedDictCounter类以及许多其他改进。

计划将 Python 2.7 作为 2.x 版本的最后一个版本,因此我们长期致力于使其成为一个不错的版本。为了帮助移植到 Python 3,2.7 中包含了 Python 3.x 系列的一些新Function。

本文并不试图提供新Function的完整规范,而是提供了一个方便的概述。有关完整的详细信息,请参阅https://docs.python.org处的 Python 2.7 文档。如果您想了解设计和实现的基本原理,请参考 PEP 以获取特定的新Function或https://bugs.python.org上讨论更改的问题。只要有可能,“ Python 新增Function”都将链接到每次更改的错误/补丁项。

Python 2.x 的 Future

Python 2.7 是 2.x 系列的最后一个主要版本,因为 Python 维护者已将其新Function开发工作的重点转移到了 Python 3.x 系列。这意味着,尽管 Python 2continue 收到错误修复,并且要进行更新以正确地在支持的 os 的新硬件和版本上进行构建,但该语言或标准库将没有新的完整Function发布。

但是,虽然 Python 2.7 和 Python 3 之间有一个很大的公共子集,并且迁移到该公共子集或直接迁移到 Python 3 所涉及的许多更改可以安全地自动化,但是其他一些更改(尤其是那些与 Unicode 处理相关的更改) )可能需要仔细考虑,最好是使用健壮的自动化回归测试套件,以便有效迁移。

这意味着 Python 2.7 将长期存在,为尚未移植到 Python 3 的生产系统提供一个稳定且受支持的基础平台。Python2.7 系列的完整预期生命周期在 PEP 373中进行了详细说明。

2.7 的长期重要性的一些关键后果是:

  • 如上所述,与早期的 2.x 版本相比,2.7 版本的维护时间更长。目前,Python 2.7 预计将一直得到核心开发团队的支持(接收安全更新和其他错误修复),直到至少 2020 年(初始发布后的 10 年,相比之下,通常的支持期为 18-24 个月)。

  • 随着 Python 2.7 标准库的老化,有效地使用 Python 包索引(直接或pass重新分配器)对于 Python 2 用户变得越来越重要。除了用于各种任务的各种各样的第三方程序包之外,可用的程序包还包括与 Python 2 兼容的 Python 3 标准库中新模块和Function的反向移植,以及可以使其更容易实现的各种工具和库。迁移到 Python3.Python 打包用户指南提供了有关从 Python 软件包索引下载和安装软件的指南。

  • 虽然现在增强 Python 2 的首选方法是在 Python 软件包索引中发布新软件包,但是这种方法不一定在所有情况下都有效,尤其是与网络安全相关的情况。在无法pass在 PyPI 上发布新的或更新的软件包来适当处理的特殊情况下,可以使用 Python 增强建议流程来为直接向 Python 2 标准库添加新Function的情况提供理由。任何此类添加及其添加的维护版本将在下面的Python 2.7 维护版本中添加的新Function部分中注明。

对于希望从 Python 2 迁移到 Python 3 的项目,或者希望在 Python 2 和 Python 3 上同时支持用户的库和框架开发人员,可以使用多种工具和指南来帮助确定合适的方法并 Management 其中的一些。涉及的技术细节。推荐的起点是将 Python 2 代码移植到 Python 3 HOWTO 指南。

弃用警告处理的更改

对于 Python 2.7,已做出一项策略决定,默认情况下将仅对开发人员感兴趣的警告静音。除非另有要求,否则现在将忽略DeprecationWarning及其子代,以防止用户看到应用程序触发的警告。在成为 Python 3.2 的分支中也进行了此更改。 (在 stdlib-sig 上讨论并在bpo-7319中进行。)

在以前的版本中,默认情况下启用DeprecationWarning消息,这为 Python 开发人员提供了明确的指示,表明他们的代码在将来的主要 Python 版本中可能会break。

但是,越来越多的基于 Python 的应用程序用户不直接参与这些应用程序的开发。 DeprecationWarning消息与此类用户无关,这使他们担心应用程序实际上是否正常运行,并使应用程序开发人员难以应对这些问题。

您可以pass使用-Wdefault(缩写为-Wd)开关运行 Python,或者pass在运行 Python 之前将 PYTHONWARNINGS环境变量设置为"default"(或"d")来重新启用DeprecationWarning消息的显示。 Python 代码还可以pass调用warnings.simplefilter('default')来重新启用它们。

unittest模块还可以在运行测试时自动重新启用弃用警告。

Python 3.1 Function

就像 Python 2.6 合并了 Python 3.0 的Function一样,版本 2.7 合并了 Python 3.1 中的一些新Function。 2.x 系列 continue 提供用于迁移到 3.x 系列的工具。

3.1 Function的部分列表,这些Function已反向移植到 2.7:

其他新的 Python3 模式警告包括:

PEP 372:将有序词典添加到集合中

常规 Python 字典以任意 Sequences 遍历键/值对。多年来,许多作者编写了替代实现,这些实现记住了最初插入密钥的 Sequences。基于这些实现的经验,2.7 在collections模块中引入了一个新的OrderedDict类。

OrderedDict API 提供与常规词典相同的接口,但是根据首次插入键的时间以保证的 Sequences 遍历键和值:

>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
...                  ('second', 2),
...                  ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]

如果新条目覆盖现有条目,则原始插入位置将保持不变:

>>> d['second'] = 4
>>> d.items()
[('first', 1), ('second', 4), ('third', 3)]

删除条目并重新插入将其移至末尾:

>>> del d['second']
>>> d['second'] = 5
>>> d.items()
[('first', 1), ('third', 3), ('second', 5)]

popitem()方法具有可选的* last 参数,默认为True。如果 last 为 true,则返回并删除最近添加的密钥;否则,返回。如果为假,则选择最早的密钥:

>>> od = OrderedDict([(x,0) for x in range(20)])
>>> od.popitem()
(19, 0)
>>> od.popitem()
(18, 0)
>>> od.popitem(last=False)
(0, 0)
>>> od.popitem(last=False)
(1, 0)

比较两个有序字典会同时检查键和值,并要求插入 Sequences 相同:

>>> od1 = OrderedDict([('first', 1),
...                    ('second', 2),
...                    ('third', 3)])
>>> od2 = OrderedDict([('third', 3),
...                    ('first', 1),
...                    ('second', 2)])
>>> od1 == od2
False
>>> # Move 'third' key to the end
>>> del od2['third']; od2['third'] = 3
>>> od1 == od2
True

OrderedDict与常规字典进行比较会忽略插入 Sequences,只会比较键和值。

OrderedDict如何工作?它会维护一个双向链接的键列表,并在插入新键时将其添加到列表中。辅助字典将键 Map 到其相应的列表节点,因此删除不必遍历整个链接列表,因此仍为 O(1)。

现在,标准库支持在多个模块中使用有序词典。

  • ConfigParser模块默认使用它们,这意味着现在可以按其原始 Sequences 读取,修改和写回配置文件。

  • collections.namedtuple()_asdict()方法现在返回一个有序字典,其值与基础 Tuples 索引的显示 Sequences 相同。

  • json模块的JSONDecoder类构造函数使用* object_pairs_hook *参数进行了扩展,以允许解码器构建OrderedDict实例。还添加了对第三方工具(如PyYAML)的支持。

See also

  • PEP 372-将有序词典添加到集合中

  • 由 Armin Ronacher 和 Raymond Hettinger 撰写的 PEP;由 Raymond Hettinger 实施。

PEP 378:千位分隔符的格式说明符

为了使程序输出更具可读性,将分隔符添加到较大的数量,使它们显示为 18,446,744,073,709,551,616,而不是 18446744073709551616,可能很有用。

完全通用的解决方案是locale模块,该模块可以使用不同的分隔符(北美为“,”,欧洲为“.”)和不同的分组大小,但是locale使用起来很复杂,不适合用于多线程应用程序,其中不同的线程针对不同的语言环境产生输出。

因此,已将简单的逗号分组机制添加到str.format()方法使用的迷你语言中。格式化浮点数时,只需在宽度和精度之间添加逗号:

>>> '{:20,.2f}'.format(18446744073709551616.0)
'18,446,744,073,709,551,616.00'

格式化整数时,请在宽度后加上逗号:

>>> '{:20,d}'.format(18446744073709551616)
'18,446,744,073,709,551,616'

这种机制根本无法适应;逗号始终用作分隔符,并且分组始终分为三位数。逗号格式化机制不像locale模块那样通用,但是更易于使用。

See also

  • PEP 378-千位分隔符的格式说明符

  • 由雷蒙德·海丁格(Raymond Hettinger)撰写的 PEP;由 Eric Smith 实现。

PEP 389:用于解析命令行的 argparse 模块

添加了用于解析命令行参数的argparse模块,以更强大的替代optparse模块。

这意味着 Python 现在支持三种不同的模块来解析命令行参数:getoptoptparseargparsegetopt模块与 C 库的getopt()函数非常相似,因此,如果您要编写finally将用 C 重写的 Python 原型,它仍然很有用。optparse变得多余,但由于有许多脚本仍在使用,因此没有计划删除它它,并且没有自动的方式来更新这些脚本。 (讨论了使argparse API 与optparse的接口保持一致,但由于过于混乱和困难而被拒绝。)

简而言之,如果您正在编写新脚本,而不必担心与 Python 早期版本的兼容性,请使用argparse而不是optparse

这是一个例子:

import argparse

parser = argparse.ArgumentParser(description='Command-line example.')

# Add optional switches
parser.add_argument('-v', action='store_true', dest='is_verbose',
                    help='produce verbose output')
parser.add_argument('-o', action='store', dest='output',
                    metavar='FILE',
                    help='direct output to FILE instead of stdout')
parser.add_argument('-C', action='store', type=int, dest='context',
                    metavar='NUM', default=0,
                    help='display NUM lines of added context')

# Allow any number of additional arguments.
parser.add_argument(nargs='*', action='store', dest='inputs',
                    help='input filenames (default is stdin)')

args = parser.parse_args()
print args.__dict__

除非您覆盖它,否则会自动添加-h--help开关,并产生格式整齐的输出:

-> ./python.exe argparse-example.py --help
usage: argparse-example.py [-h] [-v] [-o FILE] [-C NUM] [inputs [inputs ...]]

Command-line example.

positional arguments:
  inputs      input filenames (default is stdin)

optional arguments:
  -h, --help  show this help message and exit
  -v          produce verbose output
  -o FILE     direct output to FILE instead of stdout
  -C NUM      display NUM lines of added context

optparse一样,命令行开关和参数作为具有* dest *参数命名的属性的对象返回:

-> ./python.exe argparse-example.py -v
{'output': None,
 'is_verbose': True,
 'context': 0,
 'inputs': []}

-> ./python.exe argparse-example.py -v -o /tmp/output -C 4 file1 file2
{'output': '/tmp/output',
 'is_verbose': True,
 'context': 4,
 'inputs': ['file1', 'file2']}

argparseoptparse具有更好的验证能力;您可以将确切数量的参数指定为整数,pass'*'传递 0 个或多个参数,pass'+'传递 1 个或多个参数,或pass'?'传递一个可选的参数。顶级解析器可以包含子解析器,以定义具有不同开关集的子命令,如svn commitsvn checkout等。您可以将参数的类型指定为FileType,这将自动为您打开文件并了解'-'表示标准 Importing 或输出。

See also

  • argparse documentation

  • argparse 模块的文档页面。

  • 升级 optparse 代码

  • Python 文档的一部分,描述了如何转换使用optparse的代码。

  • PEP 389-argparse-新的命令行解析模块

  • PEP 由 Steven Bethard 编写和实施。

PEP 391:用于记录的基于字典的配置

logging模块非常灵活;应用程序可以定义一棵日志子系统的树,该树中的每个 Logger 都可以过滤出某些消息,以不同的方式设置它们的格式,并将消息定向到不同数量的处理程序。

所有这些灵 Active 可能需要大量配置。您可以编写 Python 语句来创建对象并设置其属性,但是复杂的设置需要冗长而乏味的代码。 logging还支持用于解析文件的fileConfig()函数,但是该文件格式不支持配置过滤器,以编程方式生成比较麻烦。

Python 2.7 添加了一个dictConfig()函数,该函数使用字典来配置日志记录。有多种方法可以从不同来源生成字典:使用代码构造一个字典;解析包含 JSON 的文件;或使用 YAML 解析库(如果已安装)。有关更多信息,请参见Configuration functions

以下示例配置了两个 Logger,即根 Logger 和名为“ network”的 Logger。发送到根 Logger 的消息将使用 syslog 协议发送到系统日志,发送到“网络”Logger 的消息将被写入network.log文件,一旦日志达到 1MB,该文件将被轮换。

import logging
import logging.config

configdict = {
 'version': 1,    # Configuration schema in use; must be 1 for now
 'formatters': {
     'standard': {
         'format': ('%(asctime)s %(name)-15s '
                    '%(levelname)-8s %(message)s')}},

 'handlers': {'netlog': {'backupCount': 10,
                     'class': 'logging.handlers.RotatingFileHandler',
                     'filename': '/logs/network.log',
                     'formatter': 'standard',
                     'level': 'INFO',
                     'maxBytes': 1000000},
              'syslog': {'class': 'logging.handlers.SysLogHandler',
                         'formatter': 'standard',
                         'level': 'ERROR'}},

 # Specify all the subordinate loggers
 'loggers': {
             'network': {
                         'handlers': ['netlog']
             }
 },
 # Specify properties of the root logger
 'root': {
          'handlers': ['syslog']
 },
}

# Set up configuration
logging.config.dictConfig(configdict)

# As an example, log two error messages
logger = logging.getLogger('/')
logger.error('Database not found')

netlogger = logging.getLogger('network')
netlogger.error('Connection failed')

Vinay Sajip 对logging模块进行了三个较小的增强,分别是:

  • SysLogHandler类现在支持pass TCP 进行系统日志记录。构造函数具有一个* socktype *参数,该参数提供要使用的套接字类型,对于 UDP 来说是socket.SOCK_DGRAM,对于 TCP 来说是socket.SOCK_STREAM。默认协议为 UDP。

  • Logger个实例获得了getChild()个方法,该方法使用相对路径检索后代 Logger。例如,pass执行log = getLogger('app')检索 Logger 后,调用log.getChild('network.listen')等效于getLogger('app.network.listen')

  • LoggerAdapter类获得了isEnabledFor()方法,该方法采用* level *级别,并返回基础 Logger 是否将处理该重要性级别的消息。

See also

  • PEP 391-用于记录的基于字典的配置

  • PEP 由 Vinay Sajip 编写和实施。

PEP 3106:字典视图

字典方法keys()values()items()在 Python 3.x 中是不同的。他们返回一个称为* view *的对象,而不是一个完全物化的列表。

在 Python 2.7 中无法更改keys()values()items()的返回值,因为太多的代码会break。而是以新名称viewkeys()viewvalues()viewitems()添加了 3.x 版本。

>>> d = dict((i*10, chr(65+i)) for i in range(26))
>>> d
{0: 'A', 130: 'N', 10: 'B', 140: 'O', 20: ..., 250: 'Z'}
>>> d.viewkeys()
dict_keys([0, 130, 10, 140, 20, 150, 30, ..., 250])

可以迭代视图,但是键和项视图的行为也类似于集合。 &运算符执行交集,而|进行并集:

>>> d1 = dict((i*10, chr(65+i)) for i in range(26))
>>> d2 = dict((i**.5, i) for i in range(1000))
>>> d1.viewkeys() & d2.viewkeys()
set([0.0, 10.0, 20.0, 30.0])
>>> d1.viewkeys() | range(0, 30)
set([0, 1, 130, 3, 4, 5, 6, ..., 120, 250])

该视图跟踪字典,并且其内容随着字典的修改而变化:

>>> vk = d.viewkeys()
>>> vk
dict_keys([0, 130, 10, ..., 250])
>>> d[260] = '&'
>>> vk
dict_keys([0, 130, 260, 10, ..., 250])

但是,请注意,遍历视图时无法添加或删除键:

>>> for k in vk:
...     d[k*2] = k
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

您可以在 Python 2.x 代码中使用 view 方法,然后 2to3 转换器会将其更改为标准的keys()values()items()方法。

See also

  • PEP 3106-更新 dict.keys()、. values()和.items()

  • PEP 由 Guido van Rossum 撰写。由 Alexandre Vassalotti 移植到 2.7; bpo-1967

PEP 3137:memoryview 对象

memoryview对象提供与bytes类型的接口匹配的另一个对象的内存内容的视图。

>>> import string
>>> m = memoryview(string.letters)
>>> m
<memory at 0x37f850>
>>> len(m)           # Returns length of underlying object
52
>>> m[0], m[25], m[26]   # Indexing returns one byte
('a', 'z', 'A')
>>> m2 = m[0:26]         # Slicing returns another memoryview
>>> m2
<memory at 0x37f080>

视图的内容可以转换为字节字符串或整数列表:

>>> m2.tobytes()
'abcdefghijklmnopqrstuvwxyz'
>>> m2.tolist()
[97, 98, 99, 100, 101, 102, 103, ... 121, 122]
>>>

memoryview对象允许修改基础对象(如果它是可变对象)。

>>> m2[0] = 75
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot modify read-only memory
>>> b = bytearray(string.letters)  # Creating a mutable object
>>> b
bytearray(b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
>>> mb = memoryview(b)
>>> mb[0] = '*'         # Assign to view, changing the bytearray.
>>> b[0:5]              # The bytearray has been changed.
bytearray(b'*bcde')
>>>

See also

  • PEP 3137-不可变的字节和可变的缓冲区

  • PEP 由 Guido van Rossum 撰写。由 Travis Oliphant,Antoine Pitrou 和其他人实施。由 Antoine Pitrou 移植到 2.7; bpo-2396

其他语言更改

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

  • 设置 Literals 的语法已从 Python 3.x 向后移植。弯曲的括号用于包围所得可变集合的内容。集合 Literals 与字典的区别在于不包含冒号和值。 {}continue 表示一个空字典;将set()用作空集。
>>> {1, 2, 3, 4, 5}
set([1, 2, 3, 4, 5])
>>> set() # empty set
set([])
>>> {}    # empty dict
{}

亚历山大·瓦萨洛蒂(Alexandre Vassalotti)向后移植; bpo-2335

  • 字典和集合推导是从 3.x 向后移植的另一个Function,它概括了列表/生成器推导,以将文本语法用于集合和字典。
>>> {x: x*x for x in range(6)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
>>> {('a'*x) for x in range(6)}
set(['', 'a', 'aa', 'aaa', 'aaaa', 'aaaaa'])

亚历山大·瓦萨洛蒂(Alexandre Vassalotti)向后移植; bpo-2333

  • with语句现在可以在一个语句中使用多个上下文 Management 器。从左到右处理上下文 Management 器,每个上下文 Management 器都视为开始一个新的with语句。这意味着:
with A() as a, B() as b:
    ... suite of statements ...

等效于:

with A() as a:
    with B() as b:
        ... suite of statements ...

contextlib.nested()函数提供了非常相似的Function,因此不再需要并且已弃用。

(在https://codereview.appspot.com/53094中提出;由 Georg Brandl 实施。)

  • 现在,在大多数平台上都可以正确舍入浮点数和字符串之间的转换。这些转换发生在许多不同的位置:str()代表浮点数和复数; floatcomplex构造函数;数字格式;使用marshalpicklejson模块序列化和反序列化浮点数和复数;用 Python 代码解析 float 和虚数 Literals;和DecimalFloat 转换。

与此相关的是,浮点数* x repr()现在基于最短的十进制字符串返回一个结果,该字符串保证在正确的舍入下(采用从半数到偶数的舍入模式)可以四舍五入为 x *。以前,它根据 x 舍入到 17 个十进制数字给出了一个字符串。

负责此改进的舍入库可在 Windows 和使用 gcc,icc 或 suncc 编译器的 Unix 平台上工作。可能在少数平台上,无法保证此代码的正确操作,因此在此类系统上不使用该代码。您可以pass检查sys.float_repr_style来确定正在使用的代码,如果正在使用新代码,则为short,如果不是,则为legacy

由 Eric Smith 和 Mark Dickinson 使用 David Gay 的dtoa.c库实现; bpo-7117

  • 从长整数和正整数到浮点的转换现在以不同的方式舍入,返回最接近该数字的浮点数。这对于可以精确转换的小整数无关紧要,但是对于不可避免地会失去精度的大数字,Python 2.7 现在更加接近。例如,Python 2.6 计算了以下内容:
>>> n = 295147905179352891391
>>> float(n)
2.9514790517935283e+20
>>> n - long(float(n))
65535L

Python 2.7 的浮点结果更大,但更接近真实值:

>>> n = 295147905179352891391
>>> float(n)
2.9514790517935289e+20
>>> n - long(float(n))
-1L

(由 Mark Dickinson 实施; bpo-3166。)

整数除法的四舍五入行为也更加准确。 (也由 Mark Dickinson 实施; bpo-1811。)

  • 消除了对复数的隐式强制。解释器将不再try在复杂对象上调用coerce()方法。 (由 Meador Inge 和 Mark Dickinson 删除; bpo-5211。)

  • str.format()方法现在支持替换字段的自动编号。这使得使用str.format()更类似于使用%s格式:

>>> '{}:{}:{}'.format(2009, 04, 'Sunday')
'2009:4:Sunday'
>>> '{}:{}:{day}'.format(2009, 4, day='Sunday')
'2009:4:Sunday'

自动编号从左到右使用字段,因此第一个{...}说明符将使用str.format()的第一个参数,下一个说明符将使用下一个参数,依此类推。您不能混合使用自动编号和显式编号(对所有指定符字段编号或不对它们进行编号),但是可以混合使用自动编号和命名字段,如上面的第二个示例所示。 (由 Eric Smith 提供; bpo-5237。)

现在,复数可以正确支持format()的用法,并且默认为右对齐。指定精度或逗号分隔适用于数字的实部和虚部,但是指定的字段宽度和对齐方式适用于整个结果1.5+3j输出。 (由 Eric Smith 提供; bpo-1588bpo-7988。)

现在,“ F”格式代码始终使用大写字符格式化其输出,因此现在将产生“ INF”和“ NAN”。 (由 Eric Smith 提供; bpo-3382。)

一个低级更改:object.__format__()方法现在会传递一个格式字符串,从而触发PendingDeprecationWarning,因为object__format__()方法将对象转换为字符串表示形式并对其进行格式化。以前,该方法将格式字符串默默地应用于字符串表示形式,但这可能会隐藏 Python 代码中的错误。如果要提供格式信息(例如对齐方式或精度),则大概是希望以特定于对象的方式应用格式。 (由 Eric Smith 固定; bpo-7994。)

  • int()long()类型获得了bit_length方法,该方法返回以二进制形式表示其参数所需的位数:
>>> n = 37
>>> bin(n)
'0b100101'
>>> n.bit_length()
6
>>> n = 2**123-1
>>> n.bit_length()
123
>>> (n+1).bit_length()
124

(由 Fredrik Johansson 和 Victor Stinner 贡献; bpo-3439。)

  • 如果相对导入(例如from .os import sep)失败,则import语句将不再try绝对导入。这修复了一个错误,但是可能会破坏某些import语句,这些语句只是偶然地起作用。 (由 Meador Inge 修复; bpo-7902。)

  • 现在,内置unicode类型的子类可以覆盖unicode()方法。 (由 Victor Stinner 实施; bpo-1583863。)

  • bytearray类型的translate()方法现在接受None作为其第一个参数。 (由乔治·布兰 del 固定; bpo-4759。)

  • 现在,使用@classmethod@staticmethod将方法包装为类或静态方法时,包装器对象现在将包装的函数公开为其__func__属性。 (由 George Sakkis 提出建议后,由 Amaury Forgeot d'Arc 提供; bpo-5982。)

  • 当使用__slots__设置一组受限的属性时,删除未设置的属性不会像您期望的那样引发AttributeError。本杰明·彼得森(Benjamin Peterson)修复; bpo-7604。)

  • 现在支持两种新编码:“ cp720”,主要用于阿拉伯文本;和“ cp858”,CP 850 的变体,添加了欧元符号。 (CP720 由bpo-1616979的 Alexander Belchenko 和 Amaury Forgeot d'Arc 提供; CP858 由bpo-8016的 Tim Hatch 提供。)

  • 现在,当try在 POSIX 平台上打开目录(由 Jan Kaliszewski; bpo-4764表示)时,file对象将在IOError异常上设置filename属性,并且现在显式检查并禁止写入只读文件对象,而不是信任 C。库以捕获并报告错误(由 Stefan Krah 修复; bpo-5677)。

  • Python 标记器现在可以自动翻译行尾,因此compile()内置函数现在可以使用任何行尾约定来接受代码。此外,它不再要求代码以换行符结尾。

  • 函数定义中的多余括号在 Python 3.x 中是非法的,这意味着您从def f((x)): pass获得语法错误。在 Python3 警告模式下,Python 2.7 现在会警告这种奇怪的用法。 (James Lingard 注意; bpo-7362。)

  • 现在可以创建对旧类对象的弱引用。new-style类始终是弱引用的。 (由 Antoine Pitrou 修复; bpo-8268。)

  • 现在,当模块对象被垃圾回收时,仅当没有其他人持有对该字典的引用(bpo-7140)时,才清除该模块的字典。

Interpreter Changes

新的环境变量 PYTHONWARNINGS允许控制警告。应将其设置为包含警告设置的字符串,该警告设置与-W开关所使用的警告设置等效,并以逗号分隔。 (由 Brian Curtin 提供; bpo-7301。)

例如,以下设置将在每次发生时打印警告,但是会将来自Cookie模块的警告变为错误。 (设置环境变量的确切语法因 os 和 Shell 程序而异.)

export PYTHONWARNINGS=all,error:::Cookie:0

Optimizations

添加了一些性能增强Function:

  • 添加了一个新的操作码来执行with语句的初始设置,查找enter()exit()方法。 (由本杰明·彼得森贡献.)

  • 现在,对于一种常见的使用模式,垃圾收集器的性能更好:当分配许多对象而不取消分配其中的任何一个时。以前,垃圾收集需要花费二次时间,但是现在,随着堆上对象数量的增加,完整垃圾收集的数量将减少。仅当中间代收集了 10 次并且中间代的幸存对象的数量超过最旧代的对象数量的 10%时,新逻辑才执行完整的垃圾回收过程。 (由 Martin vonLöwis 建议,由 Antoine Pitrou 实施; bpo-4074。)

  • 垃圾收集器试图避免跟踪不可能属于周期的简单容器。在 Python 2.7 中,这对于包含原子类型(例如 int,字符串等)的 Tuples 和字典是正确的。在传递上,也不会跟踪包含原子类型 Tuples 的 dict。pass减少收集器要考虑和遍历的对象数量,这有助于减少每个垃圾收集的成本。 (由 Antoine Pitrou 提供; bpo-4688。)

  • 长整数现在内部存储在 2 15 或 2 30 的基数中,基数是在构建时确定的。以前,它们始终以 2 15 为基数存储.使用基数 2 30 可以在 64 位计算机上显着提高性能,但是在 32 位计算机上的基准测试结果参差不齐。因此,默认值是在 64 位计算机上使用 base 2 30,在 32 位计算机上使用 base 2 15.在 Unix 上,有一个新的配置选项--enable-big-digits可用于覆盖此默认值。

除了性能改进之外,此更改对finally用户也应该是不可见的,只有一个 exception:为了进行测试和调试,有一个新的 structseq sys.long_info提供有关内部格式的信息,给出了每位的位数和字节的大小。用于存储每个数字的 C 类型:

>>> import sys
>>> sys.long_info
sys.long_info(bits_per_digit=30, sizeof_digit=4)

(由 Mark Dickinson 提供; bpo-4258。)

另一组更改使长对象缩小了几个字节:在 32 位系统上缩小了 2 个字节,在 64 位系统上缩小了 6 个字节。 (由 Mark Dickinson 提供; bpo-5260。)

  • pass收紧内部循环,执行移位而不是乘法操作以及修复不必要的额外迭代,可以使长整数的除法算法更快。各种基准测试显示长整数除法和模运算的加速比在 50%至 150%之间。 (由 Mark Dickinson 贡献; bpo-5512。)按位运算也明显更快(Gregory Smith; bpo-1087418的初始补丁)。

  • %的实现会检查左侧的操作数是否为 Python 字符串,并对其进行特殊处理;对于经常将%与字符串一起使用的应用程序(例如模板库),这会使性能提高 1-3%。 (由 Collin Winter 实施; bpo-5176。)

  • 条件为if的列表理解将编译为更快的字节码。 (Antoine Pitrou 修补程序,Jeffrey Yasskin 将其移植回 2.7; bpo-4715。)

  • pass特殊情况下的基数 10,而不是使用支持任意基数的通用转换函数,可以更快地将整数或长整数转换为十进制字符串。 (由 Gawain Bolton 修补; bpo-6713。)

  • 字符串类型(字符串,Unicode 字符串和bytearray对象)的split()replace()rindex()rpartition()rsplit()方法现在使用快速反向搜索算法,而不是逐字符扫描。有时速度要快 10 倍。(由 Florent Xicluna 添加; bpo-7462bpo-7622。)

  • 现在,picklecPickle模块会自动实习生用于属性名称的字符串,从而减少了由于取消拾取而导致的对象的内存使用量。 (由 Jake McGuire 提供; bpo-5084。)

  • cPickle模块现在对字典进行了特殊处理,几乎使腌制它们所需的时间减少了一半。 (由 Collin Winter 提供; bpo-5670。)

新模块和改进模块

与每个发行版一样,Python 的标准库得到了许多增强和错误修复。这是最值得注意的更改的部分列表,按模块名称的字母 Sequences 排列。请查阅源代码树中的Misc/NEWS文件以获得更完整的更改列表,或者查看 Subversion 日志以获取所有详细信息。

  • bdb模块的基本调试类Bdb获得了跳过模块的Function。构造函数现在采用一个包含 glob 样式的模式(例如django.*)的可迭代形式;调试器不会从与这些模式之一匹配的模块进入堆栈帧。 (由 Maru Newby 在 Senthil Kumaran 的建议下贡献; bpo-5142。)

  • binascii模块现在支持缓冲区 API,因此可以与memoryview实例和其他类似的缓冲区对象一起使用。 (由 Florent Xicluna 从 3.x 反向移植; bpo-7703。)

  • 更新的模块:bsddb模块已从 4.7.2devel9 更新到pybsddb 包的版本 4.8.4. 新版本具有更好的 Python 3.x 兼容性,各种错误修复,并添加了几个新的 BerkeleyDB 标志和方法。 (由 JesúsCeaAvión 更新; bpo-8156。可以在http://hg.jcea.es/pybsddb/file/tip/ChangeLog读取 pybsddb 更改日志。)

  • bz2模块的BZ2File现在支持上下文 Management 协议,因此您可以编写with bz2.BZ2File(...) as f:。 (由 HagenFürstenau 提供; bpo-3860。)

  • 新类:collections模块中的Counter类可用于计算数据。 Counter实例的行为与字典相似,但是对于缺少的键返回零,而不是引发KeyError

>>> from collections import Counter
>>> c = Counter()
>>> for letter in 'here is a sample of english text':
...   c[letter] += 1
...
>>> c
Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2,
'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1,
'p': 1, 'r': 1, 'x': 1})
>>> c['e']
5
>>> c['z']
0

还有另外三种Counter方法。 most_common()返回 N 个最常见的元素及其计数。 elements()返回包含元素上的迭代器,每个元素重复其次数。 subtract()采取可迭代的方式,并为每个元素减去一个,而不是相加;如果参数是字典或另一个Counter,那么将减去计数。

>>> c.most_common(5)
[(' ', 6), ('e', 5), ('s', 3), ('a', 2), ('i', 2)]
>>> c.elements() ->
   'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ',
   'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i',
   'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's',
   's', 's', 'r', 't', 't', 'x'
>>> c['e']
5
>>> c.subtract('very heavy on the letter e')
>>> c['e']    # Count is now lower
-1

由 Raymond Hettinger 贡献; bpo-1696199

新的类:OrderedDict在前面的PEP 372:将有序词典添加到集合中部分中进行了描述。

新方法:deque数据类型现在具有count()方法,该方法返回等于提供的参数* x *的所包含元素的数量,以及reverse()方法,该参数就地反转 deque 的元素。 deque还将其最大长度公开为只读maxlen属性。 (这两个Function均由 Raymond Hettinger 添加.)

namedtuple类现在具有可选的* rename 参数。如果 rename *为 true,则由于重复或不是合法的 Python 标识符而无效的字段名称将重命名为从字段在字段列表中的位置得出的合法名称:

>>> from collections import namedtuple
>>> T = namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True)
>>> T._fields
('field1', '_1', '_2', 'field2')

(由 Raymond Hettinger 添加; bpo-1818。)

最后,如果将 Map 与不是Mapping的另一个类型进行比较,则Mapping抽象 Base Class 现在返回NotImplemented。 (由 Daniel Stutzbach 固定; bpo-8729。)

  • ConfigParser模块中的解析类的构造函数现在使用* allow_no_value *参数,默认为 false;默认值为 false。如果为 true,则允许没有值的选项。例如:
>>> import ConfigParser, StringIO
>>> sample_config = """
... [mysqld]
... user = mysql
... pid-file = /var/run/mysqld/mysqld.pid
... skip-bdb
... """
>>> config = ConfigParser.RawConfigParser(allow_no_value=True)
>>> config.readfp(StringIO.StringIO(sample_config))
>>> config.get('mysqld', 'user')
'mysql'
>>> print config.get('mysqld', 'skip-bdb')
None
>>> print config.get('mysqld', 'unknown')
Traceback (most recent call last):
  ...
NoOptionError: No option 'unknown' in section: 'mysqld'

(由 Mats Kindahl 贡献; bpo-7005。)

  • 不推荐使用的函数:contextlib.nested()允许使用单个with语句处理多个上下文 Management 器,因为with语句现在支持多个上下文 Management 器。

  • 现在,cookielib模块将忽略具有无效版本字段(其中不包含整数值)的 cookie。 (由 John J. Lee 修复; bpo-3924。)

  • copy模块的deepcopy()函数现在将正确复制绑定的实例方法。 (由 Robert Collins 实施; bpo-1515。)

  • 现在,ctypes模块始终将None转换为语句为指针的参数的 C NULL 指针。 (由 Thomas Heller 更改; bpo-4606。)基础libffi library已更新至版本 3.0.9,其中包含针对不同平台的各种修复程序。 (由 Matthias Klose 更新; bpo-8142。)

  • 新方法:datetime模块的timedelta类获得了total_seconds()方法,该方法返回持续时间的秒数。 (由 Brian Quinlan 提供; bpo-5788。)

  • 新方法:Decimal类获得了from_float()类方法,该方法将浮点数精确转换为Decimal。这种精确的转换力求与浮点表示的值最接近的十进制近似值。因此,所得的十进制值将仍然包括不准确性(如果有)。例如,Decimal.from_float(0.1)返回Decimal('0.1000000000000000055511151231257827021181583404541015625')。 (由 Raymond Hettinger 实施; bpo-4796。)

现在,将Decimal实例与浮点数进行比较会根据操作数的数值产生合理的结果。以前,此类比较会回溯到 Python 的默认对象比较规则,该默认规则根据对象的类型产生任意结果。请注意,您仍不能在其他操作(例如加法)中结合使用Decimal和浮点数,因为您应该明确选择如何在 float 和Decimal之间进行转换。 (由 Mark Dickinson 固定; bpo-2531。)

Decimal的构造函数现在可以接受浮点数(由 Raymond Hettinger; bpo-8257添加)和非欧洲 Unicode 字符,例如阿拉伯语-印度数字(由 Mark Dickinson; bpo-6595贡献)。

现在,Context类的大多数方法都接受整数以及Decimal实例;唯一的 exception 是canonical()is_canonical()方法。 (JuanJoséConti 修补程序; bpo-7633。)

当将Decimal实例与字符串的format()方法一起使用时,默认的对齐方式以前是左对齐。这已更改为右对齐,这对于数字类型更明智。 (由 Mark Dickinson 更改; bpo-6857。)

现在,涉及 signalNaN 值(或sNAN)的比较将发出InvalidOperationsignal,而不是根据比较运算符静默返回 true 或 false 值。安静的 NaN 值(或NaN)现在可哈希化。 (由马克·迪金森修复; bpo-7279。)

  • 现在,difflib模块pass使用制表符而不是空格作为给出文件名的 Headers 中的分隔符,pass一次小的更改就可以生成与现代 diff / patch 工具更兼容的输出。 (由 Anatoly Techtonik 修复; bpo-7585。)

  • 现在,Distutils sdist命令将始终重新生成MANIFEST文件,因为即使未修改MANIFEST.insetup.py文件,用户也可能已经创建了一些应包含的新文件。 (由 TarekZiadé修复; bpo-8688。)

  • doctest模块的IGNORE_EXCEPTION_DETAIL标志现在将忽略包含正在测试的异常的模块的名称。 (由 Lennart Regebro 修补; bpo-7490。)

  • email模块的Message类现在将接受 Unicode 值的有效负载,自动将有效负载转换为output_charset指定的编码。 (由 R. David Murray 添加; bpo-1368247。)

  • 现在,Fraction类接受单个 float 或Decimal实例或两个有理数作为其构造函数的参数。 (由 Mark Dickinson 实施;在bpo-5812中添加了有理数,在bpo-8294中添加了浮点数/小数。)

小数和复数之间的排序比较(<<=>>=)现在提高了TypeError。这样可以解决问题,使Fraction与其他数字类型匹配。

  • 新类:ftplib模块中的FTP_TLS使用 TLS 身份验证封装以及随后的控制和数据传输提供安全的 FTP 连接。 (由 Giampaolo Rodola 提供; bpo-2054。)

由于添加了* rest *参数(由 Pablo Mouzo 修补; bpo-6845),用于二进制上传的storbinary()方法现在可以重新开始上传。

  • 新的类装饰器:functools模块中的total_ordering()接受一个类,该类定义eq()方法和lt()le()gt()ge()中的一个,并生成缺少的比较方法。由于在 Python 3.x 中不推荐使用cmp()方法,因此该装饰器使定义有序类变得更加容易。 (由 Raymond Hettinger 添加; bpo-5479。)

新函数:cmp_to_key()将采用一个老式的比较函数,该函数需要两个参数并返回一个新的可调用对象,该可调用对象可用作诸如sorted()min()max()等函数的* key *参数。主要用途是帮助使代码与 Python 3.x 兼容。 (由 Raymond Hettinger 添加.)

  • 新Function:如果垃圾收集器跟踪给定实例,则gc模块的is_tracked()返回 true,否则返回 false。 (由 Antoine Pitrou 提供; bpo-4688。)

  • gzip模块的GzipFile现在支持上下文 Management 协议,因此您可以编写with gzip.GzipFile(...) as f:(由 HagenFürstenau 提供; bpo-3860),并且它现在实现io.BufferedIOBase ABC,因此可以将其与io.BufferedReader包裹在一起以进行更快的处理(由 Nir Aides 提供; bpo-7471 )。现在,还可以pass为构造函数提供可选的时间戳来覆盖 gzipzipfile 中记录的修改时间。 (由 Jacques Frechet 提供; bpo-4272。)

gzip 格式的文件可以用零后缀填充; gzip模块现在将使用这些尾随字节。 (由 Tadek Pietraszek 和 Brian Brian 固定; bpo-2846。)

  • 新属性:hashlib模块现在具有algorithms属性,其中包含命名支持的算法的 Tuples。在 Python 2.7 中,hashlib.algorithms包含('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')。 (由 Carl Chenet 提供; bpo-7418。)

  • httplib模块使用的默认HTTPResponse类现在支持缓冲,从而可以更快地读取 HTTP 响应。 (由 KristjánValurJónsson 贡献; bpo-4879。)

HTTPConnectionHTTPSConnection类现在支持一个* source_address *参数,一个(host, port) 2Tuples 提供了将用于连接的源地址。 (由 Eldon Ziegler 提供; bpo-3972。)

  • ihooks模块现在支持相对导入。请注意,ihooks是用于自定义导入的较旧模块,已被 Python 2.0 中添加的imputil模块取代。 (Neil Schemenauer 添加了相对的 import 支持.)

  • imaplib模块现在支持 IPv6 地址。 (由 Derek Morr 贡献; bpo-1655。)

  • 新Function:inspect模块的getcallargs()接受一个 callable 及其位置参数和关键字参数,并弄清楚哪个 callable 参数将接收每个参数,并返回一个将参数名称 Map 为其值的字典。例如:

>>> from inspect import getcallargs
>>> def f(a, b=1, *pos, **named):
...     pass
>>> getcallargs(f, 1, 2, 3)
{'a': 1, 'b': 2, 'pos': (3,), 'named': {}}
>>> getcallargs(f, a=2, x=4)
{'a': 2, 'b': 1, 'pos': (), 'named': {'x': 4}}
>>> getcallargs(f)
Traceback (most recent call last):
...
TypeError: f() takes at least 1 argument (0 given)

由 George Sakkis 贡献; bpo-3135

  • 更新的模块:io库已升级到 Python 3.1 随附的版本。对于 3.1,I/O 库完全用 C 重写,并且根据执行的任务快 2 到 20 倍。原始的 Python 版本已重命名为_pyio模块。

结果是一个较小的变化:io.TextIOBase类现在具有errors属性,该属性提供用于编码和解码错误的错误设置('strict''replace''ignore'之一)。

现在,传递无效文件 Descriptors 时,io.FileIO类引发OSError。 (由 Benjamin Peterson 实现; bpo-4991。)truncate()方法现在保留文件位置;以前它会将文件位置更改为新文件的末尾。 (由 Pascal Chambon 修复; bpo-6939。)

  • 新Function:itertools.compress(data, selectors)需要两个迭代器。如果* selectors 中的对应值为 true,则返回 data *的元素:
itertools.compress('ABCDEF', [1,0,1,0,1,1]) =>
  A, C, E, F

新Function:itertools.combinations_with_replacement(iter, r)从可迭代* iter 返回所有可能的 r *-元素长度组合。与combinations()不同,可以在生成的组合中重复单个元素:

itertools.combinations_with_replacement('abc', 2) =>
  ('a', 'a'), ('a', 'b'), ('a', 'c'),
  ('b', 'b'), ('b', 'c'), ('c', 'c')

请注意,元素将根据其在 Importing 中的位置而不是其实际值而被视为唯一。

itertools.count()函数现在具有* step *参数,该参数允许以 1 以外的值递增。count()现在也允许关键字参数,并使用非整数值,例如 float 或Decimal实例。 (由 Raymond Hettinger 实施; bpo-5032。)

itertools.combinations()itertools.product()先前将ValueError提升为* r *的值大于可迭代 Importing 的值。这被认为是规范错误,因此它们现在返回一个空的迭代器。 (由 Raymond Hettinger 修复; bpo-4816。)

  • 更新的模块:json模块已升级到 simplejson 软件包的 2.0.9 版本,其中包括一个 C 扩展,可以更快地编码和解码。 (由 Bob Ippolito 贡献; bpo-4136。)

为了支持新的collections.OrderedDict类型,json.load()现在具有一个可选的* object_pairs_hook *参数,该参数将与任何解码成对列表的对象常量一起调用。 (由 Raymond Hettinger 提供; bpo-5381。)

  • 现在,mailbox模块的Maildir类将时间戳记记录在其读取的目录中,并且仅在修改时间随后更改时才重新读取它们。pass避免不必要的目录扫描,可以提高性能。 (由 A.M. Kuchling 和 Antoine Pitrou 固定; bpo-1607951bpo-6896。)

  • 新Function:math模块获得了erf()erfc()的误差函数和互补误差函数,expm1()的计算精度比exp()和_1 减去gamma()的精度更高(对于 Gamma 函数,lgamma()的自然对数) 。 (由 Mark Dickinson 和 nirinA raseliarison 提供; bpo-3366。)

  • 现在可以向multiprocessing模块的Manager*类传递一个可调用对象,无论何时启动子进程,都将调用该可调用对象,以及一组将传递给该可调用对象的参数。 (由 lekma 提供; bpo-5585。)

现在,控制工作程序池的Pool类具有一个可选的* maxtasksperchild *参数。工作进程将执行指定数量的任务,然后退出,从而导致Pool启动新工作进程。如果任务可能会泄漏内存或其他资源,或者某些任务将导致工作线程变得非常大,这将很有用。 (由 Charles Cazabon 提供; bpo-6963。)

  • nntplib模块现在支持 IPv6 地址。 (由 Derek Morr 贡献; bpo-1664。)

  • 新Function:os模块包装以下 POSIX 系统调用:getresgid()getresuid(),它们返回真实,有效和已保存的 GID 和 UID; setresgid()setresuid(),将真实,有效和保存的 GID 和 UID 设置为新值; initgroups(),它初始化当前进程的组访问列表。 (GID/UID 函数由 Travis H.贡献; bpo-6508。Jean-Paul Calderone 添加的对 initgroup 的支持; bpo-7333。)

os.fork()函数现在在子进程中重新初始化导入锁;当从线程调用fork()时,这可以解决 Solaris 上的问题。 (由 Zsolt Cserna 修复; bpo-7242。)

  • 现在,在os.path模块中,normpath()abspath()函数保留 Unicode。如果它们的 Importing 路径是 Unicode 字符串,则返回值也是 Unicode 字符串。 (normpath()bpo-5827的 Matt Giuca 固定; abspath()bpo-3426的 Ezio Melotti 固定。)

  • pydoc模块现在可以帮助您了解 Python 使用的各种符号。例如,您现在可以执行help('<<')help('@')。 (由 David Laban 提供; bpo-4739。)

  • re模块的split()sub()subn()现在接受一个可选的* flags *参数,以与该模块中的其他Function保持一致。 (由 Gregory P. Smith 添加.)

  • 新Function:runpy模块中的run_path()将在提供的* path *参数处执行代码。 * path *可以是 Python 源文件(example.py),已编译字节码文件(example.pyc),目录(./package/)或 zip 归档文件(example.zip)的路径。如果提供了目录或 zip 路径,它将被添加到sys.path的前面,并且模块main将被导入。预期目录或 zip 包含__main__.py;如果不是,则稍后可能从sys.path中的某个位置导入其他__main__.py。这使得runpy的更多机制可用于希望模仿 Python 命令行处理显式路径名的方式的脚本。 (由 Nick Coghlan 添加; bpo-6816。)

  • 新Function:在shutil模块中,make_archive()接受文件名,Files 类型(zip 或 tar 格式)和目录路径,并创建一个包含目录内容的 Files。 (由 TarekZiadé添加.)

shutilcopyfile()copytree()函数现在在要求复制命名管道时引发SpecialFileError异常。以前,代码pass打开命名管道以供读取,将命名管道视为常规文件,这将无限期地阻塞。 (由 Antoine Pitrou 修复; bpo-3002。)

  • 除非确实有必要,否则signal模块将不再重新安装 signal 处理程序,这将修复可能无法可靠捕获 EINTRsignal 的错误。 (由 Charles-Francois Natali 修复; bpo-8354。)

  • 新Function:在site模块中,三个新Function返回各种站点和用户特定的路径。 getsitepackages()返回包含所有全局站点包目录的列表,getusersitepackages()返回用户站点包目录的路径,getuserbase()返回环境变量 USER_BASE的值,并提供指向可用于存储数据的目录的路径。 (由 TarekZiadé提供; bpo-6693。)

site模块现在报告导入sitecustomize模块时发生的异常,并且将不再捕获和吞噬KeyboardInterrupt异常。 (由 Victor Stinner 修复; bpo-3137。)

  • create_connection()函数获得了一个* source_address *参数,一个(host, port) 2Tuples 给出了将用于连接的源地址。 (由 Eldon Ziegler 贡献; bpo-3972。)

recv_into()recvfrom_into()方法现在将写入支持缓冲区 API 的对象,最有用的是bytearraymemoryview对象。 (由 Antoine Pitrou 实施; bpo-8104。)

  • SocketServer模块的TCPServer类现在支持套接字超时并禁用 Nagle 算法。 disable_nagle_algorithm class 属性默认为False;如果重写为 true,则新的请求连接将设置 TCP_NODELAY 选项,以防止将许多小的发送缓冲到单个 TCP 数据包中。 timeout class 属性可以保留超时(以秒为单位),该超时将应用于请求套接字;如果在此时间内未收到任何请求,则将调用handle_timeout()并返回handle_request()。 (由 KristjánValurJónsson 贡献; bpo-6192bpo-6267。)

  • 更新的模块:sqlite3模块已更新为pysqlite package的版本 2.6.0. 2.6.0 版包含许多错误修正,并增加了从共享库加载 SQLite 扩展的Function。调用enable_load_extension(True)方法以启用扩展,然后调用load_extension()加载特定的共享库。 (由 GerhardHäring 更新.)

  • ssl模块的SSLSocket对象现在支持缓冲区 API,该缓冲区 API 修复了测试套件故障(由 Antoine Pitrou 修复; bpo-7133)并自动设置了 OpenSSL 的SSL_MODE_AUTO_RETRY,这将防止recv()操作返回触发 SSL 重新协商的错误代码(修复为 Antoine Pitrou; bpo-8222)。

ssl.wrap_socket()构造函数现在使用* ciphers *参数,该参数是一个字符串,列出了允许的加密算法;字符串的格式描述为在 OpenSSL 文档中。 (由 Antoine Pitrou 添加; bpo-8322。)

另一个更改使该扩展程序加载所有 OpenSSL 的密码和摘要算法,以便它们都可用。某些 SSL 证书无法验证,报告“未知算法”错误。 (由 Beda Kosata 报告,由 Antoine Pitrou 修复; bpo-8484。)

现在,所使用的 OpenSSL 版本可以作为模块属性ssl.OPENSSL_VERSION(字符串),ssl.OPENSSL_VERSION_INFO(5 个 Tuples)和ssl.OPENSSL_VERSION_NUMBER(整数)使用。 (由 Antoine Pitrou 添加; bpo-8321。)

  • 当值对于特定的整数格式代码(bBhHiIlLqQ之一)太大时,struct模块将不再静默忽略溢出错误。现在它总是引发struct.error异常。 (由 Mark Dickinson 更改; bpo-1523。)在tryint()方法或报告错误之前,pack()函数还将try使用index()转换和打包非整数。 (由 Mark Dickinson 更改; bpo-8300。)

  • 新Function:subprocess模块的check_output()运行带有指定参数集的命令,并在命令无错误运行时以字符串形式返回命令的输出,否则引发CalledProcessError异常。

>>> subprocess.check_output(['df', '-h', '.'])
'Filesystem     Size   Used  Avail Capacity  Mounted on\n
/dev/disk0s2    52G    49G   3.0G    94%    /\n'

>>> subprocess.check_output(['df', '-h', '/bogus'])
  ...
subprocess.CalledProcessError: Command '['df', '-h', '/bogus']' returned non-zero exit status 1

(由格雷戈里·史密斯(Gregory P. Smith)提供。)

subprocess模块现在将在收到EINTRsignal 后重试其内部系统调用。 (由几个人报告;格雷戈里·史密斯在bpo-1068268中进行了最后补丁。)

  • 新函数:symtable模块中的is_declared_global()对于显式语句为全局变量的变量返回 true,对于隐式全局变量的变量返回 false。 (由杰里米·海尔顿(Jeremy Hylton)提供。)

  • syslog模块现在将使用sys.argv[0]的值作为标识符,而不是先前的默认值'python'。 (由 Sean Reifschneider 更改; bpo-8451。)

  • sys.version_info值现在是一个名为 Tuples,具有名为majorminormicroreleaselevelserial的属性。 (由 Ross Light 提供; bpo-4285。)

sys.getwindowsversion()还返回一个命名 Tuples,其属性名为majorminorbuildplatformservice_packservice_pack_majorservice_pack_minorsuite_maskproduct_type。 (由 Brian Curtin 提供; bpo-7766。)

  • tarfile模块的默认错误处理已更改,不再抑制致命错误。默认错误级别以前为 0,这意味着错误只会导致将一条消息写入调试日志,但是由于默认情况下未激活调试日志,因此不会注意到这些错误。现在默认错误级别为 1,如果有错误,则会引发异常。 (由 LarsGustäbel 更改; bpo-7357。)

tarfile现在支持过滤要添加到 tar 文件中的TarInfo对象。调用add()时,您可以提供一个可选的* filter 参数,该参数是可调用的。对于每个要添加的文件, filter 可调用项将passTarInfo传递,并且可以对其进行修改并返回。如果可调用函数返回None,则文件将从生成的归档中排除。它比现有的 exclude *参数更强大,因此已不推荐使用。 (由 LarsGustäbel 添加; bpo-6856。)TarFile类现在还支持上下文 Management 协议。 (由 LarsGustäbel 添加; bpo-7232。)

  • threading.Event类的wait()方法现在在退出时返回内部标志。这意味着该方法通常将返回 true,因为wait()应该阻塞直到内部标志变为 true。如果提供了超时并且操作超时,则返回值将为 false。 (由 Tim Lesher 贡献; bpo-1674032。)

  • unicodedata模块提供的 Unicode 数据库现在在内部用于确定哪些字符是数字,空格或代表换行符。该数据库还包含来自Unihan.txt数据文件的信息(由 AndersChrigström 和 Amaury Forgeot d'Arc 修补; bpo-1571184),并且已更新至版本 5.2.0(由 Florent Xicluna 更新; bpo-8024)。

  • urlparse模块的urlsplit()现在以与 RFC 3986兼容的方式处理未知的 URL 方案:如果 URL 的格式为"<something>://...",则://之前的文本将被视为该方案,即使它是该模块没有的组合方案也是如此。不知道。此更改可能会破坏旧行为下起作用的代码。例如,Python 2.6.4 或 2.5 将返回以下内容:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', '', '//host/filename?query', '', '')

Python 2.7(和 Python 2.6.5)将返回:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', 'host', '/filename?query', '', '')

(Python 2.7 实际上会产生稍微不同的输出,因为它返回的是命名的 Tuples 而不是标准的 Tuples.)

urlparse模块还支持 RFC 2732(由 Senthil Kumaran 提供; bpo-2987提供)定义的 IPv6Literals 地址。

>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo')
ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]',
            path='/foo', params='', query='', fragment='')
  • 新类:weakref模块中的WeakSet类是一个仅包含对其元素的弱引用的集合;一旦没有引用指向它们,这些元素将被删除。 (最初由 Raymond Hettinger 在 Python 3.x 中实现,并由 Michael Foord 反向移植到 2.7. )

  • 当输出 XML 处理指令(看起来像<?xml-stylesheet href="#style1"?>)或 Comments(看起来像<!-- comment -->)时,ElementTree 库xml.etree不再转义与号和尖括号。 (由 Neil Muller 修补; bpo-2746。)

  • xmlrpclibSimpleXMLRPCServer模块提供的 XML-RPCClient 端和服务器pass支持 HTTP/1.1 保持活动状态以及可选地使用 gzip 编码来压缩正在交换的 XML,从而提高了性能。 gzip 压缩由SimpleXMLRPCRequestHandlerencode_threshold属性控制,该属性包含以字节为单位的大小。大于此值的响应将被压缩。 (由 KristjánValurJónsson 贡献; bpo-6267。)

  • zipfile模块的ZipFile现在支持上下文 Management 协议,因此您可以编写with zipfile.ZipFile(...) as f:。 (由 Brian Curtin 提供; bpo-5511。)

zipfile现在还支持归档空目录并正确提取它们。 (由 Kuba Wieczorek 修复; bpo-4710。)从 Files 中读取文件速度更快,并且read()readline()的交错现在可以正常工作。 (由 Nir Aides 提供; bpo-7610。)

现在,除了早期版本中接受的路径名之外,is_zipfile()函数还接受文件对象。 (由 Gabriel Genellina 提供; bpo-4756。)

writestr()方法现在具有一个可选的* compress_type *参数,该参数使您可以覆盖ZipFile构造函数中指定的默认压缩方法。 (由 Ronald Oussoren 提供; bpo-6003。)

新模块:importlib

Python 3.1 包含importlib软件包,它是对 Python import语句基础逻辑的重新实现。 importlib对于 Python 解释器的实现者和希望编写可以参与导入过程的新导入器的用户很有用。 Python 2.7 不包含完整的importlib包,而是包含一个包含单个函数import_module()的微小子集。

import_module(name, package=None)导入模块。 * name 是包含模块或软件包名称的字符串。pass提供以.字符开头的字符串(例如..utils.errors),可以进行相对导入。对于相对导入,必须提供 package *参数,该参数是将用作相对导入锚点的软件包的名称。 import_module()都将导入的模块插入sys.modules并返回模块对象。

这里有些例子:

>>> from importlib import import_module
>>> anydbm = import_module('anydbm')  # Standard absolute import
>>> anydbm
<module 'anydbm' from '/p/python/Lib/anydbm.py'>
>>> # Relative import
>>> file_util = import_module('..file_util', 'distutils.command')
>>> file_util
<module 'distutils.file_util' from '/python/Lib/distutils/file_util.pyc'>

importlib由 Brett Cannon 实现,并在 Python 3.1 中引入。

新模块:sysconfig

sysconfig模块已从 Distutils 软件包中抽出,从而成为一个新的顶层模块。 sysconfig提供用于获取有关 Python 的构建过程信息的函数:编译器开关,安装路径,平台名称以及 Python 是否从其源目录运行。

该模块中的一些Function是:

  • get_config_var()返回 Python 的 Makefile 和pyconfig.h文件中的变量。

  • get_config_vars()返回包含所有配置变量的字典。

  • get_path()返回特定模块类型的配置路径:标准库,特定于站点的模块,特定于平台的模块等。

  • 如果您正在从 Python 源代码树中运行二进制文件,则is_python_build()返回 true,否则返回 false。

有关更多详细信息和Function的完整列表,请查阅sysconfig文档。

Distutils 软件包和sysconfig现在由 TarekZiadé维护,他还启动了 Distutils2 软件包(位于https://hg.python.org/distutils2/的源存储库),用于开发 Distutils 的下一代版本。

ttk:Tk 主题小部件

Tcl/Tk 8.5 包含一组主题化的小部件,它们重新实现了基本的 Tk 小部件,但具有更可自定义的外观,因此可以更类似于本机平台的小部件。此小部件集最初称为 Tile,但在添加到 Tcl/Tck 8.5 版中后,重命名为 Ttk(“主题 Tk”)。

要了解更多信息,请阅读ttk模块文档。您可能还希望阅读有关 Ttk 主题引擎的 Tcl/Tk 手册页,网址为https://www.tcl.tk/man/tcl8.5/TkCmd/ttk_intro.htm。正在使用的 Python/Ttk 代码的一些屏幕截图位于https://code.google.com/archive/p/python-ttk/wikis/Screenshots.wiki

ttk模块由 Guilherme Polo 编写,并添加到bpo-2983中。有人提议将由马丁·富兰克林(Martin Franklin)编写并由凯文·沃尔泽(Kevin Walzer)维护的另一种版本Tile.py包含在bpo-2618中,但作者认为 Guilherme Polo 的著作更为全面。

更新的模块:unittest

unittest模块得到了极大的增强;增加了许多新Function。除非另有说明,否则大多数这些Function都是由 Michael Foord 实现的。该模块的增强版本可从https://pypi.org/project/unittest2单独下载,以与 Python 版本 2.4 至 2.6 一起使用,打包为unittest2软件包。

从命令行使用时,模块可以自动发现测试。它不像py.testnose那样精美,但是提供了一种简单的方法来运行保存在一组软件包目录中的测试。例如,以下命令将在test/子目录中搜索任何名为test*.py的可导入测试文件:

python -m unittest discover -s test

有关更多详细信息,请查阅unittest模块文档。 (在bpo-6001中开发。)

main()函数支持其他一些新选项:

  • -b--buffer将在每次测试期间缓冲标准输出和标准错误流。如果测试pass,则任何结果输出都将被丢弃;如果失败,将显示缓冲的输出。

  • -c--catch将使 Control-C break得到更合理的处理。不会立即break测试过程,而是将完成当前运行的测试,然后报告直到break为止的部分结果。如果您不耐烦,请再次按 Control-C 会立即break。

当注意到正在测试的代码或正在运行的测试已定义了自己的 signal 处理程序时,此 Control-C 处理程序将pass注意 signal 处理程序已设置并对其进行调用来try避免引起问题。如果这对您不起作用,则可以使用removeHandler()装饰器来标记应禁用 Control-C 处理的测试。

  • -f--failfast会使测试失败时立即停止执行测试,而不是 continue 执行进一步的测试。 (由 Cliff Dyer 建议,由 Michael Foord 实施; bpo-8074。)

现在,在详细模式下运行时,进度消息将显示“ x”表示预期失败,显示“ u”表示意外成功。 (由本杰明·彼得森贡献.)

测试用例可以引发SkipTest异常以跳过测试(bpo-1034053)。

assertEqual()assertTrue()assertFalse()失败的错误消息现在提供了更多信息。如果将TestCase类的longMessage属性设置为 true,则将打印标准错误消息和您提供的任何其他消息以表示失败。 (由 Michael Foord 添加; bpo-5663。)

现在,assertRaises()方法在被调用时将返回一个上下文处理程序,而无需提供可运行的对象来运行。例如,您可以这样编写:

with self.assertRaises(KeyError):
    {}['foo']

(由 Antoine Pitrou 实施; bpo-4444。)

现在支持模块和类级别的安装和拆卸夹具。模块可以包含setUpModule()tearDownModule()函数。类可以具有必须定义为类方法的setUpClass()tearDownClass()方法(使用@classmethod或等效方法)。当测试运行器切换到其他模块或类中的测试用例时,将调用这些Function和方法。

添加了方法addCleanup()doCleanups()addCleanup()允许您添加将无条件调用的清理函数(如果setUp()失败,则在setUp()之后;否则,在tearDown()之后)。这样可以在测试期间轻松地进行资源分配和释放(bpo-5679)。

添加了许多新方法,这些方法可以提供更专业的测试。其中许多方法是由 Google 工程师编写的,可在他们的测试套件中使用。 Gregory P. Smith,Michael Foord 和 GvR 致力于将它们合并到 Python 的unittest版本中。

unittest.main()现在接受一个可选的exit参数。如果为 false,则main()不会调用sys.exit(),从而允许从交互式解释器中使用main()。 (由 J. PabloFernández 提供; bpo-3379。)

TestResult具有新的startTestRun()stopTestRun()方法,它们在测试运行之前和之后立即被调用。 (由 Robert Collins 提供; bpo-5728。)

经过所有这些更改,unittest.py变得笨拙,因此该模块变成了一个包,并且代码分成了几个文件(由 Benjamin Peterson 编写)。这不会影响模块的导入或使用方式。

See also

更新的模块:ElementTree 1.3

Python 随附的 ElementTree 库版本已更新为 1.3 版。一些新Function是:

  • 现在,各种解析函数都采用* parser *关键字参数,从而提供将要使用的XMLParser实例。这样就可以覆盖文件的内部编码:
p = ET.XMLParser(encoding='utf-8')
t = ET.XML("""<root/>""", parser=p)

现在,解析 XML 时出错会引发ParseError异常,该异常的实例具有position属性,该属性包含一个(* line column *)Tuples,以提供问题的位置。

  • ElementTree 用于将树转换为字符串的代码已被大量修改,使其在许多情况下的运行速度几乎提高了一倍。 ElementTree.write()Element.write()方法现在具有* method *参数,可以是“ xml”(默认值),“ html”或“ text”。 HTML 模式将输出为<empty></empty>而不是<empty/>的空元素,而文本模式将跳过元素,仅输出文本块。如果将元素的tag属性设置为None,但将其子元素保留在原位,则在写出树时将忽略该元素,因此您无需进行更广泛的重新布置即可删除单个元素。

命名空间处理也得到了改进。现在,所有xmlns:<whatever>语句都在根元素上输出,而不是分散在整个生成的 XML 中。您可以pass设置default_namespace属性来设置树的默认名称空间,并可以使用register_namespace()注册新的前缀。在 XML 模式下,可以使用 true/false * xml_declaration *参数隐藏 XML 语句。

  • 新的Element方法:extend()将序列中的项目附加到元素的子级。元素本身的行为类似于序列,因此将子元素从一个元素移到另一个元素很容易:
from xml.etree import ElementTree as ET

t = ET.XML("""<list>
  <item>1</item> <item>2</item>  <item>3</item>
</list>""")
new = ET.XML('<root/>')
new.extend(t)

# Outputs <root><item>1</item>...</root>
print ET.tostring(new)
  • 新的Element方法:iter()产生元素的子元素作为生成器。也可以编写for child in elem:来遍历元素的子元素。现在不推荐使用现有方法getiterator(),而getchildren()则不推荐使用,该方法构造并返回子级列表。

  • 新的Element方法:itertext()产生作为元素后代的所有文本块。例如:

t = ET.XML("""<list>
  <item>1</item> <item>2</item>  <item>3</item>
</list>""")

# Outputs ['\n  ', '1', ' ', '2', '  ', '3', '\n']
print list(t.itertext())
  • 不推荐使用:如果元素具有布尔值(即if elem:),则如果该元素有任何子代,则返回 true;如果没有子代,则返回 false。这种行为令人困惑-None为假,但是没有孩子的元素也是如此吗? –因此现在将触发FutureWarning。在代码中,您应该明确:如果对孩子数量感兴趣,请 Importinglen(elem) != 0,或elem is not None

Fredrik Lundh 开发了 ElementTree 并生产了 1.3 版本。您可以在http://effbot.org/zone/elementtree-13-intro.htm阅读有关 1.3 的文章。在讨论了 python-dev 和bpo-6472之后,Florent Xicluna 更新了 Python 随附的版本。)

Build 和 C API 的更改

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

  • GNU 调试器的最新版本 GDB 7 可以为使用 Python 编写脚本。当您开始调试可执行程序 P 时,GDB 将查找名为P-gdb.py的文件并自动读取它。 Dave Malcolm 贡献了python-gdb.py,它添加了一些在调试 Python 本身时有用的命令。例如,py-uppy-down上下一个 Python 堆栈框架,该框架通常对应于几个 C 堆栈框架。 py-print打印 Python 变量的值,而py-bt打印 Python 堆栈跟踪。 (由于bpo-8032而添加。)

  • 如果您使用 Python 随附的.gdbinit文件,则当被调试的线程不包含 GIL 时,2.7 版中的“ pyo”宏现在可以正常工作。现在,宏将在打印之前获取它。 (由 Victor Stinner 贡献; bpo-3632。)

  • Py_AddPendingCall()现在是线程安全的,允许任何工作线程将通知提交到 Python 主线程。这对于异步 IO 操作特别有用。 (由 KristjánValurJónsson 提供; bpo-4293。)

  • 新Function:PyCode_NewEmpty()创建一个空的代码对象;只需文件名,函数名和第一行号。这对于try构建更有用的回溯堆栈的扩展模块很有用。以前,此类扩展需要调用PyCode_New(),后者具有更多参数。 (由 Jeffrey Yasskin 添加.)

  • 新Function:PyErr_NewExceptionWithDoc()就像现有的PyErr_NewException()一样创建一个新的异常类,但是需要一个额外的char *参数,其中包含新异常类的文档字符串。 (由 Python bug 跟踪器上的'lekma'添加; bpo-7033。)

  • 新Function:PyFrame_GetLineNumber()接收框架对象并返回框架当前正在执行的行号。以前的代码需要获取当前正在执行的字节码指令的索引,然后查找与该地址对应的行号。 (由 Jeffrey Yasskin 添加.)

  • 新Function:PyLong_AsLongAndOverflow()PyLong_AsLongLongAndOverflow()将 Python 长整数近似为 C longlong long。如果该数字太大而不能适合输出类型,那么将设置* overflow *标志并将其返回给调用方。 (由 Case Van Horsen 提供; bpo-7528bpo-7767。)

  • 新Function:由于重写了字符串到浮点转换,因此添加了新的PyOS_string_to_double()函数。现在不推荐使用旧的PyOS_ascii_strtod()PyOS_ascii_atof()函数。

  • 新Function:PySys_SetArgvEx()设置sys.argv的值,并可以选择更新sys.path以包括目录,该目录包含由sys.argv[0]命名的脚本,具体取决于* updatepath *参数的值。

添加此Function是为了关闭嵌入 Python 的应用程序的安全漏洞。旧FunctionPySys_SetArgv()始终会更新sys.path,有时会添加当前目录。这意味着,如果您运行将 Python 嵌入到其他人控制的目录中的应用程序,则攻击者可能会将 Trojan-horse 模块放在该目录中(例如,名为os.py的文件),然后您的应用程序将导入并运行该程序。

如果您维护的是嵌入 Python 的 C/C 应用程序,请检查您是否正在调用PySys_SetArgv(),并仔细考虑应用程序是否应将PySys_SetArgvEx()并将* updatepath *设置为 false。

安全问题报告为CVE-2008-5983;在bpo-5753中讨论,并由 Antoine Pitrou 修复。

  • 新的宏:Python 头文件现在定义了以下宏:Py_ISALNUMPy_ISALPHAPy_ISDIGITPy_ISLOWERPy_ISSPACEPy_ISUPPERPy_ISXDIGITPy_TOLOWERPy_TOUPPER。所有这些Function都类似于用于对字符进行分类的 C 标准宏,但是忽略了当前的语言环境设置,因为 Python 需要在多个地方以与语言环境无关的方式分析字符。 (由 Eric Smith 添加; bpo-5793。)

  • 已删除的Function:PyEval_CallObject现在仅可作为宏使用。保留了一个Function版本以保持 ABI 链接的兼容性,但是那是在 1997 年。现在肯定可以删除它。 (由 Antoine Pitrou 删除; bpo-8276。)

  • 新的格式代码:PyFormat_FromString()PyFormat_FromStringV()PyErr_Format()函数现在接受%lld%llu格式代码以显示 C 的long long类型。 (由 Mark Dickinson 提供; bpo-7228。)

  • 线程和流程分支之间的复杂交互已更改。以前,由os.fork()创建的子进程可能会失败,因为创建的子进程仅运行一个线程,该线程执行os.fork()。如果其他线程持有一个锁,例如 Python 的 import 锁,则在执行 fork 时,该锁在新进程中仍会被标记为“持有”。但是在子进程中,什么都不会释放锁,因为其他线程没有被复制,并且子进程将不再能够执行导入。

Python 2.7 在执行os.fork()之前先获取导入锁,并且还将清除使用threading模块创建的所有锁。具有内部锁或自己调用fork()的 C 扩展模块将无法从此清理中受益。

(由 Thomas Wouters 修复; bpo-1590864。)

  • Py_Finalize()函数现在调用内部threading._shutdown()函数;这可以防止在解释器关闭时引发某些异常。 (由 Adam Olsen 修补; bpo-1722344。)

  • 当使用PyMemberDef结构定义类型的属性时,Python 将不再允许您try删除或设置T_STRING_INPLACE属性。

  • 现在,由ctypes模块定义的全局符号以Py_ctypes为前缀。 (由 Thomas Heller 实施; bpo-3102。)

  • 新的配置选项:--with-system-expat开关允许构建pyexpat模块以使用系统 Expat 库。 (由 Arfrever Frehtes Taifersar Arahesis 提供; bpo-7609。)

  • 新的配置选项:--with-valgrind选项现在将禁用 pymalloc 分配器,这对于 Valgrind 内存错误检测器难以正确分析。因此,Valgrind 将更好地检测内存泄漏和溢出。 (由 James Henstridge 提供; bpo-2422。)

  • 新的配置选项:现在可以为--with-dbmliborder=提供一个空字符串,以禁用所有各种 DBM 模块。 (由 Arfrever Frehtes Taifersar Arahesis 添加; bpo-6491。)

  • 现在, configure 脚本将检查某些 32 位 Intel 芯片上的浮点舍入错误,并定义X87_DOUBLE_ROUNDING预处理程序定义。当前没有代码使用此定义,但是如果有人希望使用它,则可以使用它。 (由 Mark Dickinson 添加; bpo-2937。)

configure 现在还设置了一个 LDCXXSHARED Makefile 变量来支持 C 链接。 (由 Arfrever Frehtes Taifersar Arahesis 提供; bpo-1222585。)

  • 现在,构建过程将创建支持 pkg-config 的必要文件。 (由 Clinton Roy 提供; bpo-3585。)

  • 现在,构建过程支持 Subversion 1.7. (由 Arfrever Frehtes Taifersar Arahesis 提供; bpo-6094。)

Capsules

Python 3.1 添加了一个新的 C 数据类型PyCapsule,用于向扩展模块提供 C API。胶囊实际上是 C void *指针的持有者,并且可以作为模块属性使用。例如,socket模块的 API 公开为socket.CAPI,而unicodedata公开ucnhash_CAPI。其他扩展可以导入模块,访问其字典以获取胶囊对象,然后获取void *指针,该指针通常指向该模块的各种 API 函数的指针数组。

已有一个用于PyCObject的现有数据类型,但它不提供类型安全性。用纯 Python 编写的邪恶代码可能会pass从模块 A 中获取PyCObject并以某种方式替换模块 B 中的PyCObject来导致分段错误。胶囊知道自己的名称,而获取指针需要提供名称:

void *vtable;

if (!PyCapsule_IsValid(capsule, "mymodule.CAPI") {
        PyErr_SetString(PyExc_ValueError, "argument type invalid");
        return NULL;
}

vtable = PyCapsule_GetPointer(capsule, "mymodule.CAPI");

您可以放心vtable指向您期望的内容。如果传入了另一个胶囊,则PyCapsule_IsValid()将检测到不匹配的名称并返回 false。有关使用这些对象的更多信息,请参考为扩展模块提供 C API

Python 2.7 现在内部使用胶囊来提供各种扩展模块 API,但是PyCObject_AsVoidPtr()已被修改以处理胶囊,从而保留了与CObject接口的编译时兼容性。使用PyCObject_AsVoidPtr()将表示PendingDeprecationWarning,默认情况下它是静音的。

在 Python 3.1 中实现,并由 Larry Hastings 向后移植到 2.7; bpo-5630中讨论过。

端口特定的更改:Windows

  • msvcrt模块现在包含crtassem.h头文件中的一些常量:CRT_ASSEMBLY_VERSIONVC_ASSEMBLY_PUBLICKEYTOKENLIBRARIES_ASSEMBLY_NAME_PREFIX。 (由 David Cournapeau 贡献; bpo-4365。)

  • 现在,用于访问注册表的_winreg模块实现了CreateKeyEx()DeleteKeyEx()函数,它们是以前支持的函数的扩展版本,带有多个其他参数。 DisableReflectionKey()EnableReflectionKey()QueryReflectionKey()也经过测试和记录。 (由 Brian Curtin 实施:bpo-7347。)

  • 新的_beginthreadex() API 用于启动线程,现在使用本地线程本地存储Function。 (由 KristjánValurJónsson 提供; bpo-3582。)

  • os.kill()函数现在可在 Windows 上使用。signal 值可以是常量CTRL_C_EVENTCTRL_BREAK_EVENT或任何整数。前两个常数会将 Control-C 和 Control-Break 击键事件发送到子进程;其他任何值都将使用TerminateProcess() API。 (由 Miki Tebeka 贡献; bpo-1220212。)

  • 现在,对于空路径,os.listdir()函数正确失败了。 (由山本博和修复; bpo-5913。)

  • mimelib模块现在将在初始化时从 Windows 注册表中读取 MIME 数据库。 (Gabriel Genellina 修补程序; bpo-4969。)

端口特定的更改:Mac OS X

  • 现在,将路径/Library/Python/2.7/site-packages附加到sys.path,以便在系统安装和用户安装的相同版本的副本之间共享添加的软件包。 (由 Ronald Oussoren 更改; bpo-4865。)

Note

在版本 2.7.13 中进行了更改:自 2.7.13 起,此更改已被删除。 /Library/Python/2.7/site-packages,对于用户安装的 Python(例如来自 python.org 安装程序),Apple 提供的系统 Python 2.7 使用的 site-packages 目录不再附加到sys.path。从 macOS 10.12 开始,Apple 更改了系统 site-packages 目录的配置方式,这可能会导致 pip 组件(如 setuptools)的安装失败。为系统 Python 安装的软件包将不再与用户安装的 Python 共享。 (bpo-28440)

端口特定的更改:FreeBSD

  • FreeBSD 7.1 的SO_SETFIB常量与getsockopt()/setsockopt()一起用于选择备用路由表,现在在socket模块中可用。 (由 Kyle VanderBeek 添加; bpo-8235。)

其他更改和修复

  • 将两个基准脚本iobenchccbench添加到Tools目录中。 iobench衡量open()在执行各种操作时返回的内置文件 I/O 对象的速度,并且ccbench是并发性基准测试,它试图衡量使用不同方式执行多个任务时的计算吞吐量,线程切换延迟和 IO 处理带宽线程数。

  • Tools/i18n/msgfmt.py脚本现在可以理解.po文件中的复数形式。 (由 Martin vonLöwis 修复; bpo-5464。)

  • 从具有现有.py副本的.pyc.pyo文件导入模块时,如果原始文件名已过时,则结果代码对象的co_filename属性将被覆盖。如果文件已被重命名,移动或pass其他路径访问,则会发生这种情况。 (Ziga Seilnacht 和 Jean-Paul Calderone 的补丁; bpo-1180193。)

  • regrtest.py脚本现在带有--randseed=开关,该开关带有一个整数,该整数将用作-r选项的随机种子,该选项以随机 Sequences 执行测试。 -r选项还报告使用的种子(Collin Winter 添加.)

  • 另一个regrtest.py开关是-j,它使用一个整数来指定并行运行的测试数量。这样可以减少多核计算机上的总运行时间。此选项与其他几个选项兼容,包括-R开关,该开关可产生较长的运行时间。 (由 Antoine Pitrou 添加,bpo-6152。)这也可以与新的-F开关一起使用,该开关可以循环运行选定的测试,直到它们失败为止。 (由 Antoine Pitrou 添加; bpo-7312。)

  • 当作为脚本执行时,py_compile.py模块现在接受'-'作为参数,它将读取要编译的文件名列表的标准 Importing。 (由 PiotrOżarowski 贡献; bpo-8233。)

移植到 Python 2.7

本节列出了先前描述的更改和其他可能需要对代码进行更改的错误修正:

  • range()函数更一致地处理其参数;现在,它将在提供给它的非浮点,非整数参数上调用int()。 (由 Alexander Belopolsky 固定; bpo-1533。)

  • 字符串format()方法将用于浮点数和复数的默认精度从 6 个小数位更改为 12,这与str()使用的精度匹配。 (由 Eric Smith 更改; bpo-5920。)

  • 由于对with语句进行了优化,特殊方法enter()exit()必须属于该对象的类型,并且不能直接附加到该对象的实例。这会影响新样式的类(从object派生)和 C 扩展类型。 (bpo-6101。)

  • 由于 Python 2.6 中的一个错误,exit()方法的* exc_value 参数通常是异常的字符串表示形式,而不是实例。在 2.7 中已修复此问题,因此 exc_value *将是预期的实例。 (由 Florent Xicluna 修复; bpo-7853。)

  • 当使用__slots__设置一组受限的属性时,删除未设置的属性不会像您期望的那样引发AttributeError。本杰明·彼得森(Benjamin Peterson)修复; bpo-7604。)

在标准库中:

  • 使用datetime个实例导致一年超出支持范围的操作并不总是提高OverflowError。现在将更仔细地检查此类错误,并将引发异常。 (由 Mark Leander 报道,由 Anand B. Pillai 和 Alexander Belopolsky 修补; bpo-7150。)

  • 当将Decimal实例与字符串的format()方法一起使用时,默认的对齐方式以前是左对齐。这已更改为右对齐,这可能会更改程序的输出。 (由 Mark Dickinson 更改; bpo-6857。)

现在,涉及 signalNaN 值(或sNAN)的比较将发出 signalInvalidOperation,而不是根据比较运算符静默返回 true 或 false 值。安静的 NaN 值(或NaN)现在可哈希化。 (由马克·迪金森修复; bpo-7279。)

  • 当输出 XML 处理指令(看起来像)或 Comments(看起来像<!– comment –>)时,ElementTree 库xml.etree不再转义与号和尖括号。 (由 Neil Muller 修补; bpo-2746。)

  • 现在,当请求负数长度时,StringIO对象的readline()方法不执行任何操作,就像其他类似文件的对象一样。 (bpo-7348)。

  • syslog模块现在将使用sys.argv[0]的值作为标识符,而不是先前的默认值'python'。 (由 Sean Reifschneider 更改; bpo-8451。)

  • tarfile模块的默认错误处理已更改,不再抑制致命错误。默认错误级别以前为 0,这意味着错误只会导致将一条消息写入调试日志,但是由于默认情况下未激活调试日志,因此不会注意到这些错误。现在默认错误级别为 1,如果有错误,则会引发异常。 (由 LarsGustäbel 更改; bpo-7357。)

  • urlparse模块的urlsplit()现在以与 RFC 3986兼容的方式处理未知的 URL 方案:如果 URL 的格式为"<something>://...",则://之前的文本将被视为该方案,即使它是该模块没有的组合方案也是如此。不知道。此更改可能会破坏旧行为下起作用的代码。例如,Python 2.6.4 或 2.5 将返回以下内容:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', '', '//host/filename?query', '', '')

Python 2.7(和 Python 2.6.5)将返回:

>>> import urlparse
>>> urlparse.urlsplit('invented://host/filename?query')
('invented', 'host', '/filename?query', '', '')

(Python 2.7 实际上会产生稍微不同的输出,因为它返回的是命名的 Tuples 而不是标准的 Tuples.)

对于 Cextensions:

对于嵌入 Python 的应用程序:

Python 2.7 维护版本中添加的新Function

当情况确实需要时,可以在 Python 2.7 维护版本中添加新Function。任何此类添加都必须经过“ Python 增强建议”流程,并提出令人信服的理由,说明为什么不能pass仅将新Function添加到 Python 3 或将其发布在 Python 包索引中来充分解决这些问题。

除了下面列出的特定建议外,还有一个常规豁免,允许在任何 Python 2.7 维护版本中添加新的-3警告。

用于调试模式的两个新环境变量

在调试模式下,默认情况下不会写入[xxx refs]统计信息,现在还必须设置 PYTHONSHOWREFCOUNT环境变量。 (由 Victor Stinner 贡献; bpo-31733。)

当使用COUNT_ALLOC定义编译 Python 时,默认情况下不再分配转储计数:现在还必须设置 PYTHONSHOWALLOCCOUNT环境变量。而且,现在分配计数已转储到 stderr 中,而不是 stdout 中。 (由 Victor Stinner 贡献; bpo-31692。)

2.7.15 版中的新Function。

PEP 434:所有分支的 IDLE 增强 exception

PEP 434描述了对随 Python 一起提供的 IDLE 开发环境所做的更改的一般豁免。这项豁免使 IDLE 开发人员可以在所有受支持的 Python 2 和 3 版本中提供更一致的用户体验。

有关任何 IDLE 更改的详细信息,请参阅特定版本的 NEWS 文件。

PEP 466:Python 2.7 的网络安全增强Function

PEP 466描述了许多已被批准包含在 Python 2.7 维护版本中的网络安全增强建议,其中第一项更改出现在 Python 2.7.7 版本中。

Python 2.7.7 中添加了 PEP 466相关的Function:

  • hmac.compare_digest()从 Python 3 向后移植,以使针对计时攻击的比较操作可用于 Python 2 应用程序。 (由 Alex Gaynor 贡献; bpo-21306。)

  • OpenSSL 1.0.1g 已在 python.org 上发布的 Windows 官方安装程序中升级。 (由 Zachary Ware 提供; bpo-21462。)

Python 2.7.8 中添加了 PEP 466相关的Function:

  • hashlib.pbkdf2_hmac()是从 Python 3 向后移植的,目的是使哈希算法适合广泛用于 Python 2 应用程序的安全密码存储。 (由 Alex Gaynor 贡献; bpo-21304。)

  • OpenSSL 1.0.1h 已针对 python.org 上发布的官方 Windows 安装程序进行了升级。 (由 Zachary Ware 在bpo-21671中为 CVE-2014-0224 贡献)

Python 2.7.9 中添加了 PEP 466相关的Function:

  • 反向移植了 Python 3.4 的大多数ssl模块。这意味着ssl现在支持服务器名称指示,TLS1.x 设置,对平台证书存储的访问,SSLContext类和其他Function。 (由 Alex Gaynor 和 David Reid 提供; bpo-21308。)

有关特定的详细信息,请参见模块文档中的“添加的版本:2.7.9”Comments。

PEP 477:将 surepip(PEP 453)反向移植到 Python 2.7

PEP 477批准包含 PEP 453 surepip 模块以及由它在 Python 2.7 维护版本中启用的改进文档,该文档首先出现在 Python 2.7.9 版本中。

默认情况下自举点

新的ensurepip模块(在 PEP 453中定义)提供了一种标准的跨平台机制,可将 pip 安装程序引导到 Python 安装中。 Python 2.7.9 随附的pip版本是pip 1.5.6,将来的 2.7.x 维护版本会将 Binding 版本更新为创建候选版本时可用的最新版本pip

默认情况下,命令pippipXpipX.Y以及pip Python 软件包及其依赖项将安装在所有平台上(其中 X.Y 代表 Python 安装的版本)。

对于 CPython 源代码基于 POSIX 系统,默认情况下make installmake altinstall命令不引导pip。可以pass配置选项控制此行为,并pass Makefile 选项覆盖此行为。

在 Windows 和 Mac OS X 上,CPython 安装程序现在默认安装pip以及 CPython 本身(用户可以在安装过程中选择退出安装)。窗口用户将需要选择自动进行PATH修改,以默认情况下可从命令行使用pip,否则仍然可以pass Windows 的 Python 启动器py -m pip对其进行访问。

作为在 PEP 中讨论,平台打包程序可以选择默认情况下不安装这些命令,只要它们在被调用时就如何在该平台上安装它们提供了简单明了的指导(通常使用系统软件包 Management 器)。

Documentation Changes

作为此更改的一部分,文档的安装 Python 模块分发 Python 模块部分已完全重新设计为简短的入门指南和常见问题解答文档。现在,大多数包装文档都移到了 Python 包装 Management 机构Python 打包用户指南以及各个项目的文档中。

但是,由于该迁移目前仍未完成,因此这些指南的旧版本仍然可用安装 Python 模块(旧版)分发 Python 模块(旧版)

See also

  • PEP 453 –在 Python 安装中明确引导 pip

  • 由 Donald Stufft 和 Nick Coghlan 编写的 PEP,由 Donald Stufft,Nick Coghlan,Martin vonLöwis 和 Ned Deily 实施。

PEP 476:默认情况下为 stdlib httpClient 端启用证书验证

PEP 476更新了httplib以及使用它的模块,例如urllib2xmlrpclib,以验证服务器是否提供了由平台信任存储中的证书颁发机构签名的证书,并且其主机名与默认情况下请求的主机名匹配,从而大大改善了许多应用程序的安全性。此更改是在 Python 2.7.9 版本中进行的。

对于需要以前的旧行为的应用程序,它们可以传递备用上下文:

import urllib2
import ssl

# This disables all verification
context = ssl._create_unverified_context()

# This allows using a specific certificate for the host, which doesn't need
# to be in the trust store
context = ssl.create_default_context(cafile="/path/to/file.crt")

urllib2.urlopen("https://invalid-cert", context=context)

PEP 493:适用于 Python 2.7 的 HTTPS 验证迁移工具

PEP 493提供了其他迁移工具,以支持包含应用程序和服务的环境在构建 Client 端 HTTPS 连接时依赖于服务器证书的历史允许处理的更多增量基础结构升级过程。这些添加是在 Python 2.7.12 版本中进行的。

这些工具旨在用于在构建连接时无法修改受影响的应用程序和服务以显式传递更宽松的 SSL 上下文的情况。

对于根本无法修改的应用程序和服务,可以将新的PYTHONHTTPSVERIFY环境变量设置为0,以将整个 Python 进程恢复为 Python 2.7.8 及更早版本的默认允许行为。

对于无法修改连接构建代码但可以更改整个应用程序的情况,可以使用新的ssl._https_verify_certificates()函数在运行时调整默认行为。

新的 make regen-all 构建目标

为了简化交叉编译,并确保可以可靠地编译 CPython,而无需使用现有的 Python 版本,基于自动工具的构建系统不再try根据文件修改时间隐式重新编译生成的文件。

而是添加了一个新的make regen-all命令,以在需要时强制重新生成这些文件(例如,在已经基于预生成的版本构建 Python 的初始版本之后)。

还定义了更多选择性的再生目标-有关详细信息,请参见Makefile.pre.in

(由 Victor Stinner 在bpo-23404中贡献。)

2.7.14 版的新Function。

删除 make touch 构建目标

先前用于pass更新文件的修改时间来请求隐式重新生成生成文件的make touch构建目标已删除。

它已被新的make regen-all目标替换。

(由 Victor Stinner 在bpo-23404中贡献。)

在 2.7.14 版中更改。

Acknowledgements

作者要感谢以下人员为本文的各种草案提供建议,更正和帮助:Nick Coghlan,Philip Jenvey,Ryan Lovett,R.David Murray,Hugh Secker-Walker。