On this page
Python 3.2 新增Function
Author
- Raymond Hettinger
本文介绍了 Python 3.1 与 3.1 相比的新Function。它着重介绍了一些亮点并给出了一些示例。有关完整的详细信息,请参见Misc/NEWS文件。
See also
PEP 392-Python 3.2 发布时间表
PEP 384:定义稳定的 ABI
过去,为一个 Python 版本构建的扩展模块通常无法与其他 Python 版本一起使用。尤其是在 Windows 上,Python 的每个Function版本都需要重建一个人要使用的所有扩展模块。这项要求是对扩展模块可以使用的 Python 解释器内部自由访问的结果。
在 Python 3.2 中,有一种替代方法可供使用:扩展模块将自己限制为有限的 API(pass定义 Py_LIMITED_API)不能使用许多内部组件,而只能使用一组 API 函数,这些函数可以在多个版本中保持稳定。因此,在该模式下为 3.2 构建的扩展模块也可以与 3.3、3.4 等一起使用。仍然可以构建使用内存结构细节的扩展模块,但是对于每个Function发行版都需要重新编译。
See also
PEP 384-定义稳定的 ABI
PEP 由 Martin vonLöwis 撰写。
PEP 389:Argparse 命令行解析模块
为了克服optparse的局限性,引入了一个新的命令行解析模块argparse,该局限不支持位置参数(不仅是选项),子命令,必需的选项以及其他指定和验证选项的通用模式。
该模块作为第三方模块已经在社区中获得了广泛的成功。 argparse模块比以前的版本Function更全面,现在是命令行处理的首选模块。由于依赖于它的大量旧代码,旧模块仍保持可用。
这是一个带 Comments 的示例解析器,显示了一些Function,例如将结果限制为一组选择,在帮助屏幕中指定* metavar *,验证是否存在一个或多个位置参数以及做出必需的选项:
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特别出色的Function是能够定义子解析器,每个子解析器都有自己的参数模式并显示帮助:
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
See also
PEP 389-新的命令行解析模块
PEP 由 Steven Bethard 撰写。
升级 optparse 代码了解与optparse的区别的详细信息。
PEP 391:用于记录的基于字典的配置
logging模块提供两种配置,一种样式带有对每个选项的Function调用,另一种样式则由以ConfigParser
格式保存的外部文件驱动。这些选项不提供从 JSON 或 YAML 文件创建配置的灵 Active,也不支持增量配置,这是从命令行指定 Logger 选项所必需的。
为了支持更灵活的样式,该模块现在提供logging.config.dictConfig(),用于使用纯 Python 字典指定日志记录配置。配置选项包括格式化程序,处理程序,过滤器和 Logger。这是一个配置字典的工作示例:
{"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
See also
PEP 391-基于字典的日志记录配置
由 Vinay Sajip 撰写的 PEP。
PEP 3148:current.futures 模块
用于创建和 Management 并发的代码正在新的顶级名称空间* concurrent 中收集。它的第一个成员是 futures *软件包,该软件包提供了用于 Management 线程和进程的统一高级界面。
concurrent.futures的设计灵感来自* java.util.concurrent *包。在该模型中,正在运行的调用及其结果由Future对象表示,该对象抽象了线程,进程和远程过程调用的公用Function。该对象支持状态检查(运行或完成),超时,取消,添加回调以及对结果或异常的访问。
新模块的主要产品是Pair用于启动和 Management 调用的执行程序类。执行程序的目的是使使用现有工具进行并行调用更加容易。它们节省了设置资源池,启动调用,创建结果队列,添加超时处理以及限制线程,进程或远程过程调用的总数所需的工作量。
理想情况下,每个应用程序应在多个组件之间共享一个执行程序,以便可以集中 Management 进程和线程限制。这解决了当每个组件都有自己的竞争性资源 Management 策略时出现的设计挑战。
这两个类使用三种方法共享一个公共接口: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')
See also
PEP 3148-期货–异步执行计算
PEP 由 Brian Quinlan 撰写。
线程并行 URL 读取的代码,这是一个使用线程并行获取多个网页的示例。
PEP 3147:PYC 存储库目录
Python 在* .pyc *文件中缓存字节码的方案在具有多个 Python 解释器的环境中效果不佳。如果一个解释器遇到另一个解释器创建的缓存文件,它将重新编译源文件并覆盖该缓存文件,从而失去缓存的好处。
“ pyc 之争”的问题变得更加明显,因为它已成为 Linux 发行版附带多个版本的 Python 的常识。这些冲突也会随着 CPython 替代品(例如“空载燕子”)出现。
为了解决这个问题,Python 的导入机制已扩展为每个解释器使用不同的文件名。现在,他们将寻找“ mymodule.cpython-32.pyc”,“ mymodule.cpython-33.pyc”和“ mymodule”,而不是 Python 3.2,Python 3.3 和 Unladen Swallow 各自竞争一个名为“ mymodule.pyc”的文件。 .unladen10.pyc”。为了防止所有这些新文件杂乱无章的源目录,现在将* pyc *文件收集在软件包目录下存储的“ 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模块中的新Function:
>>> 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_compile和compileall模块已更新,以反映新的命名约定和目标目录。命令行调用* compileall 具有新选项:
-i
用于指定要编译的文件和目录的列表,-b
用于将字节码文件写入其旧位置而不是 __ pycache __ *。importlib.abc模块已更新为新的抽象 Base Class,用于加载字节码文件。已弃用了过时的 ABC
PyLoader
和PyPycLoader
(文档中包含有关如何保持 Python 3.1 兼容性的说明)。
See also
PEP 3147-PYC 存储库目录
PEP 由 Barry Warsaw 撰写。
PEP 3149:ABI 版本标记为.so 文件
PYC 存储库目录允许将多个字节码缓存文件并置。该 PEP pass为共享库文件提供通用目录和每个版本的不同名称,为共享库文件实现了类似的机制。
公共目录是“ pyshared”,pass标识 Python 实现(例如 CPython,PyPy,Jython 等),主要和次要版本号以及可选的构建标志(例如用于调试,“ m”表示 pymalloc,“ u”表示宽 unicode)。对于任意软件包“ 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'
See also
PEP 3149-ABI 版本标记的.so 文件
PEP 由 Barry Warsaw 撰写。
PEP 3333:Python Web 服务器网关接口 v1.0.1
此信息性 PEP 阐明了 WSGI 协议如何处理字节/文本问题。挑战在于,即使 HTTP 协议本身是面向字节的,Python 3 中的字符串处理也最方便地使用str类型进行处理。
PEP 将用于请求/响应头和元数据的所谓“本机字符串”与用于请求和响应主体的“字节字符串”区分开。
本机字符串始终为str类型,但仅限于* U 0000 至 U 00FF 之间的代码点,这些代码点可使用 Latin-1 编码转换为字节。这些字符串用于环境字典中的键和值以及start_response()
函数中的响应 Headers 和状态。在编码方面,它们必须遵循 RFC 2616。也就是说,它们必须是 ISO-8859-1 *字符或使用 RFC 2047 MIME 编码。
对于从 Python 2 移植 WSGI 应用程序的开发人员,要注意以下几点:
如果应用程序已在 Python 2 中使用字符串作为 Headers,则无需进行任何更改。
相反,如果是应用程序编码的输出 Headers 或解码的 ImportingHeaders,则 Headers 将需要重新编码为 Latin-1.例如,以 utf-8 编码的输出 Headers 使用
h.encode('utf-8')
现在需要使用h.encode('utf-8').decode('latin-1')
从字节转换为本地字符串。由应用程序产生或使用
write()
方法发送的值必须是字节字符串。start_response()
函数和环境必须使用本机字符串。两者不能混在一起。
对于编写 CGI 到 WSGI 路径或其他 CGI 样式协议的服务器实现者,即使底层平台可能具有不同的约定,用户也必须能够使用本机字符串访问环境。为了弥合这种差距,wsgiref模块具有一个新函数wsgiref.handlers.read_environ(),用于将os.environ中的 CGI 变量转码为本地字符串并返回新字典。
See also
PEP 3333-Python Web 服务器网关接口 v1.0.1
PEP 由 Phillip Eby 撰写。
其他语言更改
对核心 Python 语言进行的一些较小更改是:
- format()和str.format()的字符串格式获得了格式字符 # 的新Function。以前,对于二进制,八进制或十六进制的整数,它将导致输出分别以“ 0b”,“ 0o”或“ 0x”为前缀。现在,它还可以处理浮点数,复数和十进制数,即使没有数字跟随输出,也使输出始终具有小数点。
>>> format(20, '#o')
'0o24'
>>> format(12.34, '#5.0f')
' 12.'
(由 Mark Dickinson 建议,并由bpo-7094中的 Eric Smith 实现。)
- 还有一个新的str.format_map()方法pass接受任意mapping对象扩展了现有str.format()方法的Function。pass这种新方法,可以对 Python 的许多类似字典的对象(例如defaultdict,Shelf,ConfigParser或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>'
Note
(由 Raymond Hettinger 建议,并由bpo-6081中的 Eric Smith 实现。)
- 现在可以使用一个安静的选项
-q
来启动解释器,以防止在交互模式下显示版权和版本信息。可以使用sys.flags属性自省该选项:
$ python -q
>>> sys.flags
sys.flags(debug=0, division_warning=0, inspect=0, interactive=0,
optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0,
ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
(由 Marcin Wojdyr 在bpo-1772833中贡献)。
- hasattr()函数pass调用getattr()并检测是否引发异常来工作。这种技术允许它检测由getattr()或getattribute()动态创建的方法,否则这些方法将不在类字典中。以前,“ hasattr ”将捕获任何异常,可能掩盖 true 的错误。现在, hasattr *已被加强,仅捕获AttributeError并让其他异常pass:
>>> 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 修复; bpo-9666。)
>>> import math
>>> repr(math.pi)
'3.141592653589793'
>>> str(math.pi)
'3.141592653589793'
(由 Mark Dickinson 提出和实施; bpo-9337。)
- memoryview对象现在具有release()方法,并且它们现在还支持上下文 Management 协议。这样可以及时释放从原始对象请求缓冲区时获取的任何资源。
>>> with memoryview(b'abcdefgh') as v:
... print(v.tolist())
[97, 98, 99, 100, 101, 102, 103, 104]
(由 Antoine Pitrou 添加; bpo-9757。)
- 以前,如果名称作为嵌套块中的自由变量出现,则从本地名称空间中删除名称是非法的:
def outer(x):
def inner():
return x
inner()
del x
现在允许这样做。请记住,已清除了except子句的目标,因此此代码以前可与 Python 2.6 一起使用,并在 Python 3.1 中引发了SyntaxError,现在又可以正常工作:
def f():
def print_error():
print(e)
try:
something
except Exception as e:
print_error()
# implicit "del e" here
(See bpo-4617.)
- 内部的
structsequence
工具现在创建 Tuples 的子类。这意味着像os.stat(),time.gmtime()和sys.version_info返回的那些 C 结构现在像named tuple一样工作,并且现在与以 Tuples 作为参数的函数和方法一起工作。这是使 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 建议,并由本杰明·彼得森在bpo-8413实现。)
- 现在,使用 PYTHONWARNINGS环境变量代替在命令行上使用
-W
可以更轻松地控制警告:
$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
(由 Barry Warsaw 建议,由 Philip Jenvey 在bpo-7301中实施。)
- 已添加新的警告类别ResourceWarning。当检测到资源消耗或清理的潜在问题时发出。在正常发行版本中,默认情况下它是静音的,但可以passwarnings模块提供的方法或在命令行上启用。
如果gc.garbage列表不为空,则在解释器关闭时发出ResourceWarning;如果设置了gc.DEBUG_UNCOLLECTABLE,则将打印所有无法收集的对象。这是为了使程序员意识到他们的代码包含对象完成问题。
当file object被销毁而未显式关闭时,也会发出ResourceWarning。尽管此类对象的解除分配器确保其关闭了底层 os 资源(通常是文件 Descriptors),但是延迟解除分配对象可能会产生各种问题,尤其是在 Windows 下。这是从命令行启用警告的示例:
$ python -q -Wdefault
>>> f = open("foo", "wb")
>>> del f
__main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
(由bpo-10093和bpo-477863中的 Antoine Pitrou 和 Georg Brandl 添加。)
- range个对象现在支持* index 和 count 方法。这是使更多对象完全实现
collections.Sequence
抽象 Base Class的工作的一部分。结果,该语言将具有更统一的 API。此外,range对象现在支持切片和负索引,即使其值大于sys.maxsize。这使得 range *与列表更可互操作:
>>> 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)
(由bpo-9213中的 Daniel Stutzbach,bpo-2690中的 Alexander Belopolsky 和bpo-10889中的 Nick Coghlan 贡献。)
- Py2.x 的callable()内置函数已恢复。它为在类似
isinstance(x, collections.Callable)
的表达式中使用抽象 Base Class提供了一种简洁易读的替代方法:
>>> callable(max)
True
>>> callable(20)
False
(See bpo-10518.)
- Python 的导入机制现在可以加载路径名中包含非 ASCII 字符的目录中安装的模块。对于用户名中包含非 ASCII 字符的用户,这解决了主目录的加剧问题。
Note
(要求 Victor Stinner 在bpo-9425进行大量工作。)
新增,改进和不推荐使用的模块
Python 的标准库已进行了大量的维护工作,并提高了质量。
对于 Python 3.2 而言,最大的新闻是email包,mailbox模块和nntplib模块现在可以在 Python 3 中的字节/文本模型上正常使用。这是第一次,可以正确处理混合编码的消息。
在整个标准库中,对编码以及文本和字节问题的关注度更高。特别是,与 os 的交互现在可以更好地使用 Windows MBCS 编码,可识别区域设置的编码或 UTF-8 交换非 ASCII 数据。
另一个重要的胜利是增加了对* SSL *连接和安全证书的更好的支持。
另外,现在有更多的类实现context manager以支持使用with语句方便且可靠的资源清理。
R. David Murray 的广泛努力已在很大程度上固定了 Python 3 中email包的可用性。问题在于,电子邮件通常以bytes而不是str文本的形式读取和存储,并且它们在单个电子邮件中可能包含多种编码。因此,电子邮件包必须扩展以解析并生成字节格式的电子邮件。
新函数message_from_bytes()和message_from_binary_file()以及新类BytesFeedParser和BytesParser允许将二进制消息数据解析为模型对象。
给定 Importing 模型的字节数,默认情况下get_payload()将使用 MIMEHeaders 中指定的字符集对具有* 8bit 的 Content-Transfer-Encoding *的消息正文进行解码,并返回结果字符串。
给定 Importing 模型的字节数,Generator会将* Content-Transfer-Encoding 为 8bit 的消息正文转换为 7bit * * Content-Transfer-Encoding *。
使用* unknown-8bit *字符集将具有未编码的非 ASCII 字节的 Headers 视为 RFC 2047-编码。
新的类BytesGenerator产生字节作为输出,保留用于构建模型的 Importing 中存在的任何未更改的非 ASCII 数据,包括* Content-Transfer-Encoding 为 8bit *的消息正文。
smtplib SMTP类现在接受sendmail()方法的* msg 参数的字节字符串,新方法send_message()接受Message对象,并且可以选择直接从对象获取 from_addr 和 to_addrs *地址。
(由 R. David Murray bpo-4661和bpo-10321提出并实施。)
elementtree
xml.etree.ElementTree软件包及其xml.etree.cElementTree
对应版本已更新至版本 1.3.
添加了一些新的有用的Function和方法:
xml.etree.ElementTree.fromstringlist()pass片段片段构建 XML 文档
xml.etree.ElementTree.register_namespace()用于注册全局名称空间前缀
xml.etree.ElementTree.tostringlist()用于表示字符串,包括所有子列表
xml.etree.ElementTree.Element.extend()用于附加零个或多个元素的序列
xml.etree.ElementTree.Element.itertext()在元素及其子元素上创建文本迭代器
不推荐使用两种方法:
xml.etree.ElementTree.getchildren()
改用list(elem)
。xml.etree.ElementTree.getiterator()
改用Element.iter
。
有关更新的详细信息,请参见 Fredrik Lundh 网站上的Introducing ElementTree。
(由 Florent Xicluna 和 Fredrik Lundh,bpo-6472提供。)
functools
- functools模块包括一个用于装饰函数调用的新装饰器。只要预期结果相同,functools.lru_cache()就可以将重复查询保存到外部资源。
例如,将缓存装饰器添加到数据库查询Function可以保存用于流行搜索的数据库访问:
>>> import functools
>>> @functools.lru_cache(maxsize=300)
... def get_phone_number(name):
... c = conn.cursor()
... c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
... return c.fetchone()[0]
>>> for name in user_requests:
... get_phone_number(name) # cached lookup
为了帮助选择有效的高速缓存大小,已包装函数用于跟踪高速缓存统计信息:
>>> get_phone_number.cache_info()
CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
如果电话列表表已更新,则可以使用以下方法清除缓存中过时的内容:
>>> get_phone_number.cache_clear()
(由 Raymond Hettinger 贡献,并结合了 Jim Baker,Miki Tebeka 和 Nick Coghlan 的设计思想;请参阅recipe 498245,recipe 577479,bpo-10586和bpo-10593。)
- 现在,functools.wraps()装饰器添加了一个
__wrapped__
属性,该属性指向原始可调用函数。这样可以对包装的函数进行自省。如果定义,它也会复制__annotations__
。现在,它也优雅地跳过了缺少的属性,例如__doc__
,这些属性可能没有为包装的可调用对象定义。
在上面的示例中,可以pass恢复原始Function来删除缓存:
>>> get_phone_number = get_phone_number.__wrapped__ # uncached function
(由 Nick Coghlan 和 Terrence Cole 撰写; bpo-9567,bpo-3445和bpo-8814。)
- 为了帮助使用丰富的比较方法编写类,新的装饰器functools.total_ordering()将使用现有的 equal 和 inequality 方法填充其余方法。
例如,提供* __ 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))
有关排序示例和简短的排序教程,请参见Sorting HowTo教程。
(由 Raymond Hettinger 提供.)
itertools
- itertools模块具有一个新的accumulate()函数,该函数以 APL 的* scan 运算符和 Numpy 的 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()的示例,请参见随机模块的示例。
(由 Raymond Hettinger 提供,并结合了 Mark Dickinson 的设计建议.)
collections
- collections.Counter类现在具有两种形式的就地减法,即saturating subtraction的现有*-= *运算符和常规减法的新subtract()方法。前者适用于仅具有正计数的multisets,后者更适用于允许负计数的用例:
>>> from collections import Counter
>>> tally = Counter(dogs=5, cats=3)
>>> tally -= Counter(dogs=2, cats=8) # saturating subtraction
>>> tally
Counter({'dogs': 3})
>>> tally = Counter(dogs=5, cats=3)
>>> tally.subtract(dogs=2, cats=8) # regular subtraction
>>> tally
Counter({'dogs': 3, 'cats': -5})
(由 Raymond Hettinger 提供.)
- collections.OrderedDict类具有一个新方法move_to_end(),该方法采用一个现有键并将其移动到有序序列的第一个或最后一个位置。
默认是将项目移到最后一个位置。这等效于使用od[k] = od.pop(k)
更新条目。
快速移至末端的操作对于重新排序条目很有用。例如,有序字典可用于pass将条目从最早的访问到最近访问来进行老化,从而跟踪访问的 Sequences。
>>> 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同步类,用于使多个线程 await,直到所有线程都到达一个公共障碍点。屏障对于确保具有多个前提条件的任务在所有先前任务完成之前不会运行非常有用。
屏障可以与任意数量的线程一起使用。这是仅针对两个线程定义的Rendezvous的概括。
Barrier对象实现为两阶段循环障碍,适合在循环中使用。单独的* filling 和 draining *阶段可确保在其中任何一个线程可以循环并重新进入屏障之前释放所有线程(耗尽)。屏障在每个周期后完全重置。
使用障碍的示例:
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()的解决方案如何相似,但是在跨越障碍点之后,线程仍然存在并 continue 工作(汇总选票)。
如果任何前任任务可以挂起或延迟,则可以使用可选的* timeout *参数创建障碍。然后,如果在所有之前的任务都到达障碍点之前经过了超时时间,则释放所有 await 线程并引发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)
在此示例中,障碍实施了更鲁棒的规则。如果某些选举地点在午夜之前未完成,则屏障超时和选票将被密封并排入队列以备后用。
有关如何在并行计算中使用障碍的更多示例,请参见屏障同步模式。另外,在signal 量小书中,*第 3.6 *节中有一个简单而透彻的障碍说明。
(由 KristjánValurJónsson 贡献,Jeffrey Yasskin 在bpo-8777中进行了 API 审查。)
日期时间和时间
>>> 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并除以float和int个对象。现在timedelta个对象可以彼此分割。
datetime.date.strftime()方法不再限于 1900 年之后的年份。新的受支持的年份范围是从 1000 到 9999(含)。
每当在时间 Tuples 中使用两位数的年份时,解释便受
time.accept2dyear
约束。默认值为True
,这意味着对于两位数的年份,将根据 Management%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'
现在,一些Function已大大扩展了日期范围。如果time.accept2dyear
为 false,则time.asctime()函数将接受适合 C int 的任何年份,而time.mktime()和time.strftime()函数将接受相应的 os 函数支持的整个范围。
(由 Alexander Belopolsky 和 Victor Stinner 在bpo-1289118,bpo-5094,bpo-6641,bpo-2706,bpo-1777412,bpo-8013和bpo-10827中贡献。)
math
math模块已更新为具有 C99 标准启发的六个新Function。
isfinite()Function提供了一种可靠且快速的方法来检测特殊值。它返回True
表示常规数字,返回False
表示* Nan 或 Infinity *:
>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]
expm1()函数针对* x *的较小值计算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()函数计算概率 Integration 或高斯误差函数。互补误差函数erfc()为1 - erf(x)
:
>>> from math import erf, erfc, sqrt
>>> erf(1.0/sqrt(2.0)) # portion of normal distribution within 1 standard deviation
0.682689492137086
>>> erfc(1.0/sqrt(2.0)) # portion of normal distribution outside 1 standard deviation
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0
gamma()函数是阶乘函数的连续扩展。有关详情,请参见https://en.wikipedia.org/wiki/Gamma_function。因为该函数与阶乘相关,所以即使* x *的值很小,该函数也会增大,因此还有一个lgamma()函数可用于计算 gamma 函数的自然对数:
>>> 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()的抽象 Base Class:
class Temperature(metaclass=abc.ABCMeta):
@abc.abstractclassmethod
def from_fahrenheit(cls, t):
...
@abc.abstractclassmethod
def from_celsius(cls, t):
...
(补丁由 Daniel Urban 提交; bpo-5867。)
io
io.BytesIO有一个新方法getbuffer(),它提供的Function类似于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'
(由bpo-5506中的 Antoine Pitrou 提供。)
reprlib
为自定义容器编写repr()方法时,很容易忘记处理成员引用回容器本身的情况。 Python 的内置对象(例如list和set)pass在表示形式字符串的递归部分中显示“…”来处理自引用。
为了帮助编写这样的repr()方法,reprlib模块具有一个新的修饰符recursive_repr(),用于检测对repr()的递归调用并代替占位符字符串:
>>> class MyList(list):
... @recursive_repr()
... def __repr__(self):
... return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>
(由 Raymond Hettinger 在bpo-9826和bpo-9840中贡献。)
logging
除了上述基于字典的配置外,logging软件包还有许多其他改进。
日志记录文档增加了basic tutorial,advanced tutorial和cookbook的日志记录配方。这些文档是学习日志记录的最快方法。
logging.basicConfig()设置函数获得了* style *参数,以支持三种不同类型的字符串格式。对于传统的%格式,它默认为“%”;对于新的str.format()样式,它可以设置为“ {”;对于string.Template提供的 shell 样式格式,它可以设置为“ $”。以下三个配置是等效的:
>>> 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")
如果在发生日志事件之前未设置任何配置,那么对于WARNING
或更高级别的事件,现在存在一个默认配置,该配置使用指向StreamHandler的StreamHandler。以前,根据logging.raiseExceptions
的值,在设置配置之前发生的事件将引发异常或静默删除该事件。新的默认处理程序存储在logging.lastResort中。
过滤器的使用已得到简化。谓词可以是返回True
或False
的任何 Python 可调用对象,而不是创建Filter对象。
还有许多其他改进可以增加灵 Active 并简化配置。有关 Python 3.2 中更改的完整列表,请参见模块文档。
csv
csv模块现在支持新的方言unix_dialect,该方言适用于所有字段,并使用传统的 Unix 样式(以'\n'
作为行终止符)。注册的方言名称为unix
。
csv.DictWriter有一个新方法writeheader(),用于写出初始行以记录字段名称:
>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
... {'name': 'tom', 'dept': 'accounting'},
... {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"
(Jay Talbot 在bpo-5975中提出了新的方言,而 Ed Abraham 在bpo-1537721中提出了新的方法。)
contextlib
有一个新的Function令人惊叹的新工具ContextDecorator有助于创建context manager,该context manager函数充当函数装饰器。
为方便起见,contextmanager()使用了此新Function,因此不需要额外的精力来支持这两个角色。
基本思想是上下文 Management 器和函数装饰器都可以用于操作前和操作后包装器。上下文 Management 器使用with语句包装一组语句,函数装饰器包装在函数中包含的一组语句。因此,有时需要编写可以在任一个角色中使用的行动前或行动后包装器。
例如,有时使用可以跟踪进入时间和退出时间的 Logger 包装函数或语句组很有用。 contextmanager()并没有为任务编写函数装饰器和上下文 Management 器,而是在单个定义中提供了两种Function:
from contextlib import contextmanager
import logging
logging.basicConfig(level=logging.INFO)
@contextmanager
def track_entry_and_exit(name):
logging.info('Entering: %s', name)
yield
logging.info('Exiting: %s', name)
以前,这只能用作上下文 Management 器:
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()
试图同时完成两个角色对这项技术有一些限制。上下文 Management 器通常可以灵活地返回with语句可用的参数,但是函数修饰符没有并行性。
在上面的示例中,* track_entry_and_exit *上下文 Management 器没有一种干净的方法来返回日志记录实例以用于封闭语句的主体中。
(由 Michael Foord 在bpo-9110中贡献。)
小数和小数
马克·迪金森(Mark Dickinson)设计了一种优雅而有效的方案,以确保每当它们的实际值相等(bpo-8188)时,不同的数字数据类型将具有相同的哈希值:
assert hash(Fraction(3, 2)) == hash(1.5) == \
hash(Decimal("1.5")) == hash(complex(1.5, 0))
一些散列细节pass新属性sys.hash_info公开,该属性描述了散列值的位宽,素数模数,* infinity 和 nan *的散列值以及用于 a 的虚部的乘数。数:
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)
限制各种数字类型的互操作性的早期决定已经放松。在诸如Decimal('1.1') + float('1.1')
之类的算术表达式中进行隐式混合仍然不被支持(并且不明智),因为后者在构造二进制浮点数的过程中会丢失信息。但是,由于可以将现有的浮点值无损地转换为十进制或有理数表示形式,因此将它们添加到构造函数中并支持混合类型比较是有意义的。
decimal.Decimal构造函数现在直接接受float对象,因此不再需要使用from_float()方法(bpo-8257)。
现在完全支持混合类型比较,因此可以将Decimal个对象直接与float和fractions.Fraction(bpo-2531和bpo-8188)进行比较。
对fractions.Fraction进行了类似的更改,因此不再需要from_float()和from_decimal()方法(bpo-8294):
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
decimal模块的另一个有用更改是Context.clamp
属性现在是公共的。这对于创建与 IEEE 754 中指定的十进制互换格式相对应的上下文很有用(请参阅bpo-8540)。
(由 Mark Dickinson 和 Raymond Hettinger 贡献.)
ftp
ftplib.FTP类现在支持上下文 Management 协议,以无条件使用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.mmap和fileinput.input())也可以自动关闭上下文 Management 器:
with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
for line in f:
process(line)
(由bpo-4972的 TarekZiadé和 GiampaoloRodolà以及bpo-8046和bpo-1286的 Georg Brandl 贡献。)
FTP_TLS类现在接受一个* context *参数,该参数是一个ssl.SSLContext对象,该参数允许将 SSL 配置选项,证书和私钥 Binding 到一个(可能长期存在)的结构中。
(由 GiampaoloRodolà贡献; bpo-8806。)
popen
os.popen()和subprocess.Popen()函数现在支持with语句,用于自动关闭文件 Descriptors。
(由 Antoine Pitrou 和 Brian Curtin 在bpo-7461和bpo-10554中贡献。)
select
现在,select模块公开了一个新的常量属性PIPE_BUF,该属性提供了最小的字节数,当select.select()表示管道已准备好进行写操作时,这些字节保证不被阻塞。
>>> import select
>>> select.PIPE_BUF
512
(在 Unix 系统上可用.SébastienSablé在bpo-9862中进行了修补)
gzip 和 zipfile
gzip.GzipFile现在实现io.BufferedIOBase 抽象 Base Class(truncate()
除外)。它还具有peek()方法,并支持不可搜索以及零填充文件对象。
gzip模块还具有compress()和decompress()Function,以便于进行内存中的压缩和解压缩。请记住,在压缩和解压缩之前,文本需要编码为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'
(由bpo-3488中的 Anand B. Pillai 以及bpo-9962,bpo-1675951,bpo-7471和bpo-2846中的 Antoine Pitrou,Nir Aides 和 Brian Brian 贡献。)
另外,内部对zipfile.ZipExtFile
类进行了重新处理以表示存储在存档中的文件。新的实现明显更快,可以包装在io.BufferedReader对象中以提高速度。它还解决了对* read 和 readline *的交错调用导致错误结果的问题。
(由 Nir Aides 在bpo-7610中提交的补丁。)
tarfile
TarFile类现在可以用作上下文 Management 器。另外,它的add()方法具有一个新选项* filter *,该选项控制将哪些文件添加到归档中并允许编辑文件元数据。
新的* filter 选项替换了现在不推荐使用的较旧的,灵 Active 较差的 exclude 参数。如果指定,则可选的 filter *参数必须为keyword argument。用户提供的过滤器函数接受TarInfo对象并返回更新的TarInfo对象,或者如果要排除文件,该函数可以返回None
:
>>> import tarfile, glob
>>> def myfilter(tarinfo):
... if tarinfo.isfile(): # only save real files
... tarinfo.uname = 'monty' # redact the user name
... return tarinfo
>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
... for filename in glob.glob('*.txt'):
... tf.add(filename, filter=myfilter)
... tf.list()
-rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501 123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501 1399 2011-01-26 17:59:11 semaphore_notes.txt
(由 TarekZiadé提出,LarsGustäbel 在bpo-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 在bpo-7418中建议。)
ast
ast模块有一个很棒的通用工具,可以使用 PythonLiterals 语法安全地评估表达式字符串。 ast.literal_eval()函数可替代易于使用的内置eval()函数,是一种安全的替代方法。 Python 3.2 将bytes和setLiterals 添加到支持的类型列表中:字符串,字节,数字,Tuples,列表,字典,集合,布尔值和None
。
>>> from ast import literal_eval
>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}
>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>
(由本杰明·彼得森和乔治·布兰 del 实施)。
os
不同的 os 对文件名和环境变量使用各种编码。 os模块提供了两个新Functionfsencode()和fsdecode(),用于编码和解码文件名:
>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'
一些 os 允许直接访问环境中的编码字节。如果是这样,则os.supports_bytes_environ常量为 true。
要直接访问已编码的环境变量(如果有),请使用新的os.getenvb()函数或使用__,它是os.environ的字节版本。
(由 Victor Stinner 贡献.)
shutil
shutil.copytree()函数具有两个新选项:
-
- ignore_dangling_symlinks *:
symlinks=False
时,以便函数复制符号链接指向的文件,而不是符号链接本身。如果文件不存在,此选项将使引发的错误静音。
- ignore_dangling_symlinks *:
-
- copy_function *:是可调用的,将用于复制文件。默认情况下使用shutil.copy2()。
(由 TarekZiadé提供.)
此外,shutil模块现在支持archiving operations的 zip 文件,未压缩的 tarfile,gzip 压缩的 tarfile 和 bzip 压缩的 tarfile。并且具有注册其他归档文件格式(例如 xz 压缩的 tarfile 或自定义格式)的Function。
主要Function是make_archive()和unpack_archive()。默认情况下,两者都在当前目录(可以passos.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. 它具有两个新Function。
如果存在未提交更改的活动事务,则
sqlite3.Connection.in_transit
属性为 true。sqlite3.Connection.enable_load_extension()和sqlite3.Connection.load_extension()方法允许您从“ .so”文件加载 SQLite 扩展。一种众所周知的扩展是随 SQLite 一起分发的全文搜索扩展。
(由 R. David Murray 和 Shashwat Anand 贡献; bpo-8845。)
html
引入了一个新的html模块,该模块只有一个函数escape(),用于从 HTML 标记转义保留字符:
>>> import html
>>> html.escape('x > 2 && x < 7')
'x > 2 && x < 7'
socket
socket模块具有两项新改进。
套接字对象现在具有detach()方法,该方法将套接字置于关闭状态,而无需实际关闭基础文件 Descriptors。然后可以将后者重新用于其他目的。 (由 Antoine Pitrou 添加; bpo-8524。)
socket.create_connection()现在支持上下文 Management 协议以无条件使用socket.error异常并在完成后关闭套接字。 (由 GiampaoloRodolà提供; bpo-9794。)
ssl
ssl模块添加了许多Function,以满足对安全(加密,身份验证)互联网连接的通用要求:
新类SSLContext充当持久 SSL 数据(例如协议设置,证书,私钥和各种其他选项)的容器。它包括一个wrap_socket(),用于根据 SSL 上下文创建 SSL 套接字。
新Functionssl.match_hostname()pass实现 HTTPS 规则(来自 RFC 2818)来支持更高级别协议的服务器身份验证,该规则也适用于其他协议。
现在,ssl.wrap_socket()构造函数使用* ciphers *参数。 * cipher *字符串使用OpenSSL documentation中描述的格式列出了允许的加密算法。
与最新版本的 OpenSSL 链接时,ssl模块现在支持 TLS 协议的服务器名称指示扩展,从而允许在单个 IP 端口上使用不同的证书的多个“虚拟主机”。此扩展仅在 Client 端模式下受支持,并且pass将* server_hostname *参数传递给ssl.SSLContext.wrap_socket()来激活。
ssl模块中已添加了各种选项,例如OP_NO_SSLv2可以禁用不安全且过时的 SSLv2 协议。
该扩展现在可以加载所有 OpenSSL 密码和摘要算法。如果某些 SSL 证书无法验证,则将它们报告为“未知算法”错误。
现在可以使用模块属性ssl.OPENSSL_VERSION(字符串),ssl.OPENSSL_VERSION_INFO(5 个 Tuples)和ssl.OPENSSL_VERSION_NUMBER(整数)访问正在使用的 OpenSSL 版本。
(由 Antoine Pitrou 在bpo-8850,bpo-1589,bpo-8322,bpo-5639,bpo-4870,bpo-8484和bpo-8321中贡献。)
nntp
nntplib模块具有经过改进的实现,具有更好的字节和文本语义以及更实用的 API。这些改进破坏了与 Python 3.1 中的 nntplib 版本的兼容性,后者本身部分无法正常工作。
还添加了对pass隐式(使用nntplib.NNTP_SSL)和显式(使用nntplib.NNTP.starttls())TLS 进行安全连接的支持。
(由bpo-9360中的 Antoine Pitrou 和bpo-1926中的 Andrew Vant 贡献。)
certificates
http.client.HTTPSConnection,urllib.request.HTTPSHandler和urllib.request.urlopen()现在采用可选参数,以允许对一组证书颁发机构进行服务器证书检查,这是 HTTPS 的公共用途中建议的。
(由bpo-9003的 Antoine Pitrou 添加。)
imaplib
pass新的imaplib.IMAP4.starttls方法添加了对标准 IMAP4 连接上显式 TLS 的支持。
(由bpo-4471的 Lorenzo M. Catucci 和 Antoine Pitrou 提供。)
http.client
http.client模块对 API 进行了一些小的改进。不再支持旧式的 HTTP 0.9 简单响应,并且所有类均已弃用* strict *参数。
现在,HTTPConnection和HTTPSConnection类具有用于(主机,端口)Tuples 的* source_address *参数,该参数指示从何处构建 HTTP 连接。
对证书检查和 HTTPS 虚拟主机的支持已添加到HTTPSConnection。
连接对象上的request()方法允许使用可选的* body 参数,以便可以使用file object来提供请求的内容。方便地, body *参数现在也接受一个iterable对象,只要它包含一个显式的Content-Length
Headers 即可。该扩展接口比以前灵活得多。
要pass代理服务器构建 HTTPS 连接,有一个新的set_tunnel()方法为 HTTP Connect 隧道设置主机和端口。
为了匹配http.server的行为,HTTPClient 端库现在还使用 ISO-8859-1(Latin-1)编码对 Headers 进行编码。它已经对传入的报头执行了此操作,因此现在对于传入和传出流量而言,行为都是一致的。 (请参见bpo-10980中 Armin Ronacher 的工作。)
unittest
unittest 模块具有许多改进,支持对软件包的测试发现,在交互提示符下更轻松的实验,新的测试用例方法,改进的针对测试失败的诊断消息以及更好的方法名称。
- 命令行调用
python -m unittest
现在可以接受文件路径而不是模块名称,以运行特定的测试(bpo-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,bpo-9754贡献。)
另一种新方法assertCountEqual()用于比较两个可迭代对象,以确定它们的元素计数是否相等(无论 Sequences 如何,是否存在相同的元素且出现的次数相同):
def test_anagram(self):
self.assertCountEqual('algorithm', 'logarithm')
(由 Raymond Hettinger 提供.)
单元测试模块的主要Function是在测试失败时做出有意义的诊断。如果可能,将记录故障以及输出的差异。这对于分析失败的测试运行的日志文件特别有用。但是,由于差异有时可能很大,因此有一个新的maxDiff属性设置显示的差异的最大长度。
此外,模块中的方法名称已进行了多次清理。
例如,assertRegex()是assertRegexpMatches()
的新名称,由于测试使用的是re.search()而不是re.match(),因此被错误命名。现在,其他使用正则表达式的方法都使用缩写形式“ Regex”代替“ Regexp”来命名-这与其他 unittest 实现中使用的名称匹配,与re模块的 Python 旧名称匹配,并且具有明确的驼峰式 Shell。
(由 Raymond Hettinger 贡献,由 Ezio Melotti 实施.)
- 为了提高一致性,不建议使用一些长期存在的方法别名,以使用首选名称:
Note
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 提供; bpo-9424。)
assertDictContainsSubset()
方法已弃用,因为它以错误的 Sequences 错误地使用了参数。这造成了难以调试的错觉,其中TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})
之类的测试将失败。
(由 Raymond Hettinger 提供.)
random
random模块中的整数方法现在可以更好地产生均匀分布。以前,他们使用int(n*random())
计算选择,只要* n *不为 2 的幂,该选择就会有轻微偏差。现在,从一个范围直至下一个 2 的幂进行多次选择,并且仅当它处于0 <= x < n
范围内时,才保留选择。受影响的函数和方法是randrange(),randint(),choice(),shuffle()和sample()。
(由 Raymond Hettinger 提供; bpo-9025。)
poplib
POP3_SSL类现在接受一个* context *参数,这是一个ssl.SSLContext对象,该参数允许将 SSL 配置选项,证书和私钥 Binding 到一个(可能是长期存在的)结构中。
(由 GiampaoloRodolà贡献; bpo-8807。)
asyncore
asyncore.dispatcher现在提供了一个handle_accepted()方法,该方法返回一个(sock,addr)对,当与新的远程端点实际构建连接时会调用该对。应该将其用作旧handle_accept()的替代,并避免用户直接调用accept()。
(由 GiampaoloRodolà贡献; bpo-6706。)
tempfile
tempfile模块具有一个新的上下文 Management 器TemporaryDirectory,它可以轻松确定性地清除临时目录:
with tempfile.TemporaryDirectory() as tmpdirname:
print('created temporary dir:', tmpdirname)
(由 Neil Schemenauer 和 Nick Coghlan 提供; bpo-5178。)
inspect
- inspect模块具有新Functiongetgeneratorstate(),可轻松识别生成器迭代器的当前状态:
>>> from inspect import getgeneratorstate
>>> def gen():
... yield 'demo'
>>> g = gen()
>>> getgeneratorstate(g)
'GEN_CREATED'
>>> next(g)
'demo'
>>> getgeneratorstate(g)
'GEN_SUSPENDED'
>>> next(g, None)
>>> getgeneratorstate(g)
'GEN_CLOSED'
(由 Rodolpho Eckhardt 和 Nick Coghlan,bpo-10220提供。)
- 为了支持无法激活动态属性的查找,inspect模块具有新Functiongetattr_static()。与hasattr()不同,这是一个 true 的只读搜索,保证在搜索时不会更改状态:
>>> 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>
Note
(由 Michael Foord 提供.)
pydoc
现在,pydoc模块提供了经过改进的 Web 服务器界面,以及新的命令行选项-b
来自动打开浏览器窗口以显示该服务器:
$ pydoc3.2 -b
(由 Ron Adam 提供; bpo-2001。)
dis
dis模块获得了两个用于检查代码的新Functioncode_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 的实现方式和亲自了解语言语法的内在Function变得更加容易。
(由 Nick Coghlan 在bpo-9147中贡献。)
dbm
现在,所有数据库模块都支持get()
和setdefault()
方法。
(由 Ray Allen 在bpo-9523中建议。)
ctypes
新类型ctypes.c_ssize_t表示 C ssize_t
数据类型。
site
site模块具有三个新Function,可用于报告给定 Python 安装的详细信息。
getsitepackages()列出所有全局站点程序包目录。
getuserbase()报告用户可以存储数据的基本目录。
getusersitepackages()显示用户特定的站点软件包目录路径。
>>> 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'
方便地,某些网站Function可以直接从命令行访问:
$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages
(由 TarekZiadé在bpo-6693中贡献。)
sysconfig
新的sysconfig模块使发现平台和安装之间不同的安装路径和配置变量变得很简单。
该模块提供用于平台和版本信息的访问简单访问Function:
get_platform()返回值,例如* linux-i586 或 macosx-10.6-ppc *。
get_python_version()返回 Python 版本字符串,例如“ 3.2”。
它还提供对与distutils使用的七个命名方案之一相对应的路径和变量的访问。这些包括* posix_prefix , posix_home , posix_user , nt , nt_user , os2 和 os2_home *:
get_paths()制作一个字典,其中包含当前安装方案的安装路径。
get_config_vars()返回平台特定变量的字典。
还有一个方便的命令行界面:
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
脚本文件可以包含 continue 调试的continue
和next
命令。Pdb
类构造函数现在接受* nosigint *参数。新命令:
l(list)
,ll(long list)
和source
用于列出源代码。新命令:
display
和undisplay
用于显示或隐藏表达式的值(如果已更改)。新命令:
interact
,用于启动一个交互式解释器,其中包含在当前作用域中找到的全局名称和本地名称。可以pass断点编号清除断点。
(由 Georg Brandl,Antonio Cuni 和 Ilya Sandler 贡献.)
configparser
修改了configparser模块,以提高默认解析器及其支持的 INI 语法的可用性和可预测性。旧的ConfigParser
类已被删除,取而代之的是SafeConfigParser
,该类又被重命名为ConfigParser。现在默认情况下已关闭对内联 Comments 的支持,并且单个配置源中不允许节或选项重复。
配置解析器基于 Map 协议获得了新的 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 文件结构。用户可以指定替代的选项/值定界符和 Comments 前缀,更改* 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'
还引入了许多较小的Function,例如支持在读取操作中指定编码,为 get 函数指定后备值或直接从字典和字符串中读取。
(所有更改均由ŁukaszLanga 提供.)
urllib.parse
urllib.parse模块进行了许多可用性改进。
urlparse()函数现在支持IPv6地址,如 RFC 2732中所述:
>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
path='/foo/',
params='',
query='',
fragment='')
urldefrag()函数现在返回named tuple:
>>> r = urllib.parse.urldefrag('http://python.org/about/#target')
>>> r
DefragResult(url='http://python.org/about/', fragment='target')
>>> r[0]
'http://python.org/about/'
>>> r.fragment
'target'
而且,urlencode()函数现在更加灵活,可以为* query 参数接受字符串或字节类型。如果是字符串,则将 safe , encoding 和 error *参数发送到quote_plus()进行编码:
>>> urllib.parse.urlencode([
... ('type', 'telenovela'),
... ('name', '¿Dónde Está Elisa?')],
... encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'
如解析 ASCII 编码字节所述,所有urllib.parse函数现在都接受 ASCII 编码的字节字符串作为 Importing,只要它们不与常规字符串混合即可。如果将 ASCII 编码的字节字符串作为参数给出,则返回类型也将是 ASCII 编码的字节字符串:
>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
path=b'/about/', params=b'', query=b'', fragment=b'')
(Nick Coghlan,Dan Mahn 和 Senthil Kumaran 在bpo-2987,bpo-5468和bpo-9873中的工作。)
mailbox
在 R. David Murray 的共同努力下,mailbox模块已针对 Python 3.2 修复。挑战在于邮箱最初是用文本界面设计的,但是最好用bytes表示电子邮件,因为消息的各个部分可能具有不同的编码。
该解决方案利用email软件包的二进制支持来解析任意电子邮件。此外,该解决方案需要更改许多 API。
如预期的那样,用于mailbox.Mailbox个对象的add()方法现在接受二进制 Importing。
StringIO和文本文件 Importing 已弃用。另外,如果使用非 ASCII 字符,则字符串 Importing 将尽早失败。以前,在后续步骤中处理电子邮件时,它将失败。
还支持二进制输出。 get_file()方法现在以二进制模式返回文件(在该模式下,它曾经错误地将文件设置为文本模式)。还有一个新的get_bytes()方法,该方法返回与给定* key *对应的消息的bytes表示形式。
仍然可以使用旧 API 的get_string()方法获得非二进制输出,但是这种方法不是很有用。相反,最好从Message对象中提取消息或从二进制 Importing 中加载消息。
(由 R. David Murray 贡献,在 Steffen Daode Nurpmeso 的努力下,由 Victor Stinner 在bpo-9124中进行了初步修补。)
turtledemo
turtle模块的演示代码已从* Demo *目录移至主库。它包括十几个带有生动显示的示例脚本。现在位于sys.path上,它可以直接从命令行运行:
$ python -m turtledemo
(已从 Alexander_ Belopolsky 在bpo-10199中的 Demo 目录中移出。)
Multi-threading
- 串行化了同时运行的 Python 线程(通常称为GIL或全局翻译锁)执行的机制。目标之一是更可预测的切换间隔,并由于锁定争用和随后发生的系统调用数而减少了开销。允许线程切换的“检查间隔”的概念已被放弃,并由以秒表示的绝对持续时间代替。此参数可passsys.setswitchinterval()调整。当前默认为 5 毫秒。
可以从python-dev 邮件列表消息读取有关实现的其他详细信息(但是,此消息中公开的“优先级请求”尚未保留以供包含)。
(由 Antoine Pitrou 提供.)
现在,常规锁和递归锁对其acquire()方法接受一个可选的* timeout *参数。 (由 Antoine Pitrou 提供; bpo-7316。)
同样,threading.Semaphore.acquire()也获得了* timeout *参数。 (由 Torsten Landschoff 提供; bpo-850728。)
现在,可以使用 Pthread 在平台上pass signal break常规和递归锁获取。这意味着可以pass将 SIGINT 反复发送到进程(pass在大多数 shell 中按 Ctrl C)来成功杀死在获取锁时死锁的 Python 程序。 (由 Reid Kleckner 贡献; bpo-8844。)
Optimizations
添加了许多小的性能增强Function:
现在速度损失已经不复存在,开始使用设置符号编写成员资格测试是可行的。这种样式在语义上既清晰又在操作上很快捷:
extension = name.rpartition('.')[2]
if extension in {'xml', 'html', 'xhtml', 'css'}:
handle(name)
(补丁和其他测试由 Dave Malcolm 提供; bpo-6690)。
- 现在,使用pickle模块对数据进行序列化和反序列化的速度快了好几倍。
(由bpo-9410和bpo-3873的 Alexandre Vassalotti,Antoine Pitrou 和 Unladen Swallow 小组贡献。)
- 现在,用key function调用list.sort()和sorted()中使用的Timsort algorithm可以更快地运行并且使用更少的内存。以前,列表的每个元素都被一个临时对象包装,该对象记住与每个元素相关的键值。现在,键和值的两个数组并行排序。这样可以节省排序包装程序消耗的内存,并节省因委派比较而浪费的时间。
(Daniel Stutzbach 在bpo-9915中修补)。
- 只要对多个键重复相同的字符串,就可以提高 JSON 解码性能并减少内存消耗。此外,当
sort_keys
参数为 true 时,JSON 编码现在使用 C 加速。
(由bpo-7451中的 Antoine Pitrou 和bpo-10314中的 Raymond Hettinger 和 Antoine Pitrou 贡献。)
- 递归锁(使用threading.RLock() API 创建)现在受益于 C 实现,它使它们与常规锁一样快,并且比以前的纯 Python 实现快 10 到 15 倍。
(由 Antoine Pitrou 提供; bpo-3001。)
- 现在,bytes,bytearray和str对象上的
split()
,rsplit()
,splitlines()
和replace()
方法使用 stringlib 中的快速搜索算法。同样,rfind()
,rindex()
,rsplit()
和rpartition()
也使用该算法。
(由 Florent Xicluna 在bpo-7622和bpo-7462中修补)。
- 现在,整数到字符串的转换一次可以工作两个“数字”,从而减少了除法和模运算的次数。
(bpo-6713,作者是 Gawain Bolton,Mark Dickinson 和 Victor Stinner。)
还有其他一些次要的优化。现在,当一个操作数比另一个操作数大得多时,集差分的运行速度更快(由bpo-8685的 Andress Bennetts 修补)。 array.repeat()
方法的实现速度更快(Alexander Belopolsky 的bpo-1569291)。 BaseHTTPRequestHandler
具有更有效的缓冲(Andrew Schaaf 的bpo-3709)。 operator.attrgetter()Function已加快(Christos Georgiou bpo-10160)。 ConfigParser
加载多行参数的速度更快一些(ŁukaszLanga 的bpo-7113)。
Unicode
Python 已更新为Unicode 6.0.0。该标准的更新添加了 2,000 多个新字符,其中包括对手机非常重要的emoji符号。
此外,更新后的标准还更改了两个 Kannada 字符(U 0CF1,U 0CF2)和一个新 Tai Lue 数字字符(U 19DA)的字符属性,从而使前者有资格在标识符中使用,而使后者失去资格。有关更多信息,请参见Unicode 字符数据库更改。
Codecs
支持添加了* cp720 *阿拉伯 DOS 编码(bpo-1616979)。
MBCS 编码不再忽略错误处理程序参数。在默认的严格模式下,当遇到不可解码的字节序列时,它将引发UnicodeDecodeError,对于无法编码的字符,它将引发UnicodeEncodeError。
MBCS 编解码器支持用于解码的'strict'
和'ignore'
错误处理程序,以及用于编码的'strict'
和'replace'
。
要模拟 Python3.1 MBCS 编码,请选择用于解码的'ignore'
处理程序和用于编码的'replace'
处理程序。
在 Mac OS X 上,Python 使用'utf-8'
而不是区域设置编码来解码命令行参数。
默认情况下,tarfile在 Windows 上使用'utf-8'
编码(而不是'mbcs'
),在所有 os 上使用'surrogateescape'
错误处理程序。
Documentation
该文档 continue 得到改进。
快速链接表已添加到冗长的部分(例如Built-in Functions)的顶部。在itertools的情况下,链接附带备忘单样式的摘要表,以提供概述和 Memory 点动,而无需阅读所有文档。
在某些情况下,纯 Python 源代码可以作为文档的有用辅助,因此现在许多模块都提供了指向最新版本源代码的快速链接。例如,functools模块文档的顶部有一个快速链接,标记为:
Note
源代码 Lib/functools.py。
(由 Raymond Hettinger 提供;请参阅rationale。)
文档现在包含更多示例和食谱。特别地,re模块具有一个广泛的部分正则表达式示例。同样,itertools模块 continue 用新的Itertools Recipes更新。
datetime模块现在具有纯 Python 的辅助实现。未更改任何Function。这只是提供了易于阅读的替代实现。
(由 Alexander Belopolsky 在bpo-9528中贡献。)
- 无需维护的
Demo
目录已被删除。一些演示已集成到文档中,有些已移至Tools/demo
目录,而另一些已完全删除。
(由 Georg Brandl 在bpo-7962中贡献。)
IDLE
- 现在,格式菜单中有一个选项,可以pass去除尾随空格来清除源文件。
(由 Raymond Hettinger 提供; bpo-5150。)
- Mac OS X 上的 IDLE 现在可与 Carbon AquaTk 和 Cocoa AquaTk 一起使用。
(由 Kevin Walzer,Ned Deily 和 Ronald Oussoren 贡献; bpo-6075。)
Code Repository
除了位于http://svn.python.org的现有 Subversion 代码存储库之外,现在还位于https://hg.python.org/的Mercurial存储库。
在 3.2 版本之后,有计划切换到 Mercurial 作为主要存储库。这种分布式版本控制系统应使社区成员更容易创建和共享外部变更集。有关详情,请参见 PEP 385。
要学习使用新版本控制系统,请参阅Quick Start或商业流程指南。
Build 和 C API 的更改
对 Python 的构建过程和 C API 的更改包括:
现在,已在
make altinstall
(bpo-10679)上安装了* idle , pydoc 和 2to3 *脚本,并带有特定于版本的后缀。现在,即使在狭窄的 unicode 构建(Py_UNICODE_TOLOWER,Py_UNICODE_ISDECIMAL 等)上,访问 Unicode 数据库的 C 函数也可以接受并返回整个 Unicode 范围内的字符。 Python 的一个明显区别是unicodedata.numeric()现在为较大的代码点返回正确的值,而repr()可能会将更多字符视为可打印。
(由 Bupjoe Lee 报告,由 Amaury Forgeot D'Arc 修复; bpo-5127。)
- 现在,默认情况下,在受支持的编译器上启用了计算的 goto(由 configure 脚本检测)。pass指定
--without-computed-gotos
仍然可以有选择地禁用它们。
(由 Antoine Pitrou 提供; bpo-9203。)
- 选项
--with-wctype-functions
已删除。现在,内置的 unicode 数据库可用于所有Function。
(由 Amaury Forgeot D'Arc 提供; bpo-9210。)
- 哈希值现在是新类型
Py_hash_t
的值,该值定义为与指针相同的大小。以前它们是 long 型的,在某些 64 位 os 上,它们仍然只有 32 位长。作为此修复程序的结果,set和dict现在可以在具有 64 位指针的构建中容纳2**32
个条目以上(以前,它们可以增长到该大小,但是其性能却急剧下降)。
(由 Raymond Hettinger 建议并由 Benjamin Peterson 实施; bpo-9778。)
一个新的宏
Py_VA_COPY
复制变量参数列表的状态。它等效于 C99 * va_copy *,但在所有 Python 平台(bpo-2443)上都可用。新的 C API 函数PySys_SetArgvEx()允许嵌入式解释器设置sys.argv,而无需同时修改sys.path(bpo-5753)。
PyEval_CallObject
现在仅以宏形式可用。由于向后兼容的原因而保留的函数语句现在已删除-该宏于 1997 年引入(bpo-8276)。有一个新FunctionPyLong_AsLongLongAndOverflow(),类似于PyLong_AsLongAndOverflow()。它们都可以将 Python int转换为本机固定宽度类型,同时提供对转换不适合的情况(bpo-7767)的检测。
现在,如果 Python 字符串以* NUL 终止,则PyUnicode_CompareWithASCIIString()函数将返回 not equal *。
有一个新FunctionPyErr_NewExceptionWithDoc()类似于PyErr_NewException(),但允许指定文档字符串。这使 C 异常与纯 Python 异常(bpo-7033)具有相同的自我记录Function。
使用
--with-valgrind
选项进行编译时,在 Valgrind 下运行时,将自动禁用 pymalloc 分配器。当在 Valgrind 下运行时,这可以改进内存泄漏检测,同时在其他时间(bpo-2422)利用 pymalloc。从* PyArg_Parse *函数中删除了
O?
格式。该格式已不再使用,并且从未被记录过(bpo-8837)。
C-API 还有许多其他小的更改。有关完整列表,请参见Misc/NEWS文件。
另外,Mac OS X 版本有许多更新,有关详细信息,请参见Mac/BuildScript/README.txt。对于运行 32/64 位版本的用户,Mac OS X 10.6 上的默认 Tcl/Tk 存在一个已知问题。因此,我们建议安装更新的替代方案,例如ActiveState Tcl/Tk 8.5.9。有关更多详细信息,请参见https://www.python.org/download/mac/tcltk/。
移植到 Python 3.2
本节列出了先前描述的更改和其他可能需要对代码进行更改的错误修正:
configparser模块有大量清理工作。主要更改是将旧的
ConfigParser
类替换为长期存在的首选替代方法SafeConfigParser
。此外,还有许多较小的不兼容性:现在可以在get()和set()操作上验证插值语法。在默认插值方案中,只有两个带百分号的标记有效:
%(name)s
和%%
,后者是转义的百分号。现在,set()和add_section()方法验证值是实际的字符串。以前,可能会无意中引入不受支持的类型。
现在,来自单一来源的重复节或选项会引发DuplicateSectionError或DuplicateOptionError。以前,重复项会静默覆盖以前的条目。
现在默认情况下禁用内联 Comments,因此现在可以安全地在值中使用 ; 字符。
现在可以缩进 Comments。因此,为了使 ; 或 # 以多行值出现在行的开头,必须对其进行插值。这样可以防止值中的 Comments 前缀字符被误认为是 Comments。
""
现在是有效值,不再自动转换为空字符串。对于空字符串,请在一行中使用"option ="
。
nntplib模块经过了广泛的重新设计,这意味着其 API 通常与 3.1 API 不兼容。
为了清楚起见,
array.tostring()
和array.fromstring()
已重命名为array.tobytes()
和array.frombytes()
。旧名称已被弃用。 (请参阅bpo-8990。)PyArg_Parse*()
Function:已删除“ t#”格式:改用“ s#”或“ s *”
- “ w”和“ w#”格式已被删除:请改用“ w *”
在 3.1 中弃用的
PyCObject
类型已被删除。要将不透明的 C 指针包装在 Python 对象中,应改用PyCapsule API。新类型具有用于传递类型安全信息的定义明确的接口,以及用于调用析构函数的较简单的签名。sys.setfilesystemencoding()
函数被删除,因为它的设计有缺陷。random.seed()函数和方法现在使用 sha512 哈希函数对字符串种子加盐。要访问* seed 的先前版本以重现 Python 3.1 序列,请将 version 参数设置为 1 *
random.seed(s, version=1)
。删除了先前不推荐使用的
string.maketrans()
函数,以支持静态方法bytes.maketrans()和bytearray.maketrans()。此更改解决了string模块支持哪些类型的混淆。现在,str,bytes和bytearray各自具有自己的 maketrans 和 translate 方法,并带有适当类型的中间转换表。
(由 Georg Brandl 提供; bpo-5675。)
- 删除了先前不推荐使用的
contextlib.nested()
函数,以支持可以接受多个上下文 Management 器的简单的with语句。后一种技术更快(因为它是内置的),并且在其中一个引发异常时,它可以更好地完成多个上下文 Management 器的终结工作:
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 将其隐式编码为字节。这是有问题的,因为它假设了正确的编码,并且当写入结构的固定长度段时,可变长度编码可能会失败。
诸如struct.pack('<6sHHBBB', 'GIF87a', x, y)
之类的代码应重写为使用字节而不是文本struct.pack('<6sHHBBB', b'GIF87a', x, y)
。
(由 David Beazley 发现并由 Victor Stinner 修复; bpo-10783。)
现在,当解析失败时,xml.etree.ElementTree类会引发xml.etree.ElementTree.ParseError。以前它提出了xml.parsers.expat.ExpatError。
浮点数上更长的新str()值可能会破坏依赖于旧输出格式的 doctest。
在subprocess.Popen中,* close_fds 的默认值现在在 Unix 下为
True
;在 Windows 下,如果三个标准流设置为None
,则为True
,否则为False
。以前, close_fds *默认情况下始终为False
,当打开的文件 Descriptors 泄漏到子进程中时,这将导致难以解决的错误或争用条件。从urllib.request和http.client中删除了对旧版 HTTP 0.9 的支持。这样的支持仍然存在于服务器端(在http.server中)。
(由 Antoine Pitrou,bpo-10711贡献。)
- 现在,在发生超时的情况下,处于超时模式的 SSL 套接字会引发socket.timeout,而不是通用的SSLError。
(由 Antoine Pitrou,bpo-10272贡献。)
具有误导性的FunctionPyEval_AcquireLock()和PyEval_ReleaseLock()已被正式弃用。应该改用线程状态感知的 API(例如PyEval_SaveThread()和PyEval_RestoreThread())。
由于安全风险,不建议使用
asyncore.handle_accept()
,并添加了新Functionasyncore.handle_accepted()
来代替它。
(由 Giampaolo Rodola 在bpo-6706中贡献。)
- 由于采用了新的GIL实现,因此无法再在Py_Initialize()之前调用PyEval_InitThreads()。