Python 3000 新特性介绍<o:p></o:p>
Unicode,编解码器和 I/O<o:p></o:p>
Python 3000正在迁移到 Java 处理 Unicode 的模型,那就是:(不可变的)文本字符串就是 Unicode ,而二进制数据则由另一个(可变的)“字节数组”的类型来表达。 另外词法分析器也对 Unicode 更加友好了:默认的源代码的编码将会是 UTF-8, 而且非 ASCII 字母也可以用在标识符里面了,现在还在进行一些这方面讨论,主要集中在标准化、明确非 ASCII 字母表、是否应该某种程度地支持自右向左的程序几个问题上。不过标准库自然还是会一如既往地只使用 ASCII 字符做标识符,并且限制在注释和字面字符串(string literals)中使用非 ASCII 字母,在单元测试中测试一些 Unicode 特性或者是作者名字的情形除外。<o:p></o:p>
我们将会使用 "..." 或 '...' 来表达字面 Unicode 字符串,而 b"..." 和 b'...' 用来表达字面字节数组。比如, b'abc' 等价于使用表达式 bytes([97, 98, 99]) 创建的字节数组。<o:p></o:p>
我们采用一种和以前稍微不同的编解码器:在 Python 2 中,编解码器既可以接受 Unicode 也可以接受8位字节数组作为输入,同样也可以输出这两种对象的任何一种,而在 Py3k 中编码过程总是从 Unicode 字符串到字节数组的转换,而解码过程则总是相反的方向。 这意味着我们必须丢弃一些不符合这个模型的编解码器,比如 rot13,base64 和 bz2 (当然我们仍然支持这些转换操作,只不过不通过 encode/decode API 了)。<o:p></o:p>
新的 I/O 库<o:p></o:p>
针对上面的这些变化 I/O 库自然要做相应的变化了。正好我也早有重写这个库的意思, 以前我就想要除掉它对 C stdio 库的依赖。而现在字节数组和字符串的区别也需要 它的 API 有一个(细微的)变化,the two projects were undertake hand in hand。 在这个新库中,打开二进制流(使用模式 "rb" 或 "wb" 打开)和文本流 (模式名中不包含 "b" )之间将会有明显的区别。文本流有一个新属性,encoding,你可以在打开流的时候显式地当参数传给它;如果没有指定编码,就会使用系统默认的编码( 打开一个存在的文件时也可以猜它的编码)。<o:p></o:p>
对二进制流的读操作返回的是字节数组,而对文本流的读操作返回(Unicode)字符串; 写操作也类似。给二进制流写入字符串或者给文本流写入字节数组都会抛出异常。<o:p></o:p>
除此以外,API 基本还是和以前差不多。同样会有一个内置的 open() 函数, 新的 I/O 库在 io 模块中。这个模块还包含不同类型流的抽象基类 (抽象基类见下文),一个 StringIO 的新实现,还有一个类似 StringIO 的 BytesIO,它实现了一个二进制流,因此也就只能读写字节数组。<o:p></o:p>
print和格式化<o:p></o:p>
还有两个和 I/O 有关的新特性:古老的 print 语句变成了 print() 函数, 而诡异的字符串格式化操作符 % 也被字符串对象的新方法 format() 取代。<o:p></o:p>
把 print 变成函数常常让人大吃一惊(makes some eyes roll)。但是它确实还是有一些 好处的,比如:这样可以方便地将使用 print 的代码重构成(比如说)使用 logging 模块; 并且 print 的语法一直以来也都存在一些争议,比如 >>file 和末尾跟一个逗号的独特 语义。现在由关键字参数来完成这些任务,大家都满意了。<o:p></o:p>
同样,新的 format() 方法也避免了一些 % 操作符的缺陷,特别是语句 "%s" % x 当 x 是个元组时让人意外的结果,和许多人经常犯的忘记敲 %(name)s 最后的这个 's' 的失误。新的格式化字符串使用 {0},{1},{2}, ... 来引用传给 format() 方法位置参数, 用 {a}, {b}, ... 来引用关键字参数。还有其他一些特性如用 {a.b.c} 来访问对象属性,甚至可以用 {a[b]} 访问字典和序列。可以用 {a:8} 来指定转换字符串的长度,使用这个语法也可以传递其他格式化选项。<o:p></o:p>
format() 方法还可以不同的维度进行扩展:通过定义 __format__() 方法,任何类型可以定义 他们自己格式化的方式和解释格式化参数的方式;你还可以创建自定义的格式化 class ,它可以用来 (比如)自动将局部名字空间当作格式化的参数。<o:p></o:p>
对class和类型系统的改变<o:p></o:p>
你可能已经猜到了,"classic classes" 终于退出了历史舞台。内置类型 object 成为新 class 的默认基类。这使得一系列新特性得以实现:<o:p></o:p>
<!---->1. <!---->类装饰器。他们和函数装饰器非常像::<o:p></o:p>
<!---->Ø <!---->@art_decoclass C: ...<o:p></o:p>
函数和方法的定义可以加上“签名(annotated)”,语言核心本身并不给这些签名赋予 特殊的含义(只是在内省时会提供这些元数据),不过一些标准库却可以;比如, generic function (见下文)可以使用这些元数据。这个新语法可读性非常好::<o:p></o:p>
<!---->Ø <!---->def foobar(a: Integer, b: Sequence) -> String: ...<o:p></o:p>
<!---->2. <!---->新的 metaclass 语法。以前是在 class 定义体中设置一个变量 __metaclass__ , 现在你得在 class 定义头中指定一个关键字参数,比如::<o:p></o:p>
<!---->Ø <!---->class C(bases, metaclass=MyMeta): ...<o:p></o:p>
自定义 class 字典。如果 metaclass 定义了 __prepare__() 方法,那么在进入 class 定义体之前会调用它,用它返回的对象取代标准的字典,而 class 定义体中的属性就用这个对象进行存储。比如说,你可以用这个特性来实现一个 "struct" 类型,因为对于 "struct" 来说属性定义的 顺序是非常关键的。<o:p></o:p>
<!---->3. <!---->你可以动态地指定基类,比如::<o:p></o:p>
<!---->Ø <!---->bases = (B1, B2)class C(*bases): ...<o:p></o:p>
在 class 定义头中还可以使用其他的关键字参数;这些参数都被传给 metaclass 的 __new__ 方法。<o:p></o:p>
你可以通过定义 __instancecheck__() 或 __subclasscheck__() 方法 重载相应的 __isinstance__() 、 __issubclass__() 语义。 如果定义了这两个方法, isinstance(x, C) 等价于 C.__instancecheck__(x) ,而 issubclass(D, C) 等价于 C.__subclasscheck__(D) 。<o:p></o:p>
抽象基类(Abstract Base Classes, ABC)。如果你想要定义一个 class ,它的实例 的行为类似 mapping (举个例子),你就可以继承 class abc.Mapping 。 一方面,这个 class 提供 mix-in 的行为,可以提供大部分 UserDict 和 DictMixin 的功能。另一方面,系统地使用这种 ABC 能够帮助大型框架减少猜测 并获得正确的行为:在 Python 2 中,要判断一个实现了 __getitem__() 方法的对象究竟是序列(sequence)还是映射(mapping),还真不是那么简单的事情。 我们提供了下面这些ABC:Hashable, Iterable, Iterator, Sized, Container, Callable; Set, MutableSet; Mapping, MutableMapping; Sequence, MutableSequence; Number, Complex, Real, Rational, Integer。 io 模块 也定义了许多ABC,所以在 python 历史上,终于对以前定义模糊的“file-like”这个概念 第一次有了明确的规范。ABC 框架的强大能力来源于(从 zope interface 中学来的)能够 注册某一个 class X ,让它“虚拟地继承于”一个 ABC Y,而 X 和 Y 可以由不同的作者编写,也可以出现在不同的包中。(需要澄清的是:如果使用的是虚拟继承,class Y 的 mix-in 行为并不会 作用在 class X 上;唯一的效果只是 issubclass(X, Y) 返回 True )<o:p></o:p>
抽象基类(ABC)需要确保子类实现了完整的接口,为了支持抽象基类的定义, 我们引入装饰器 @abc.abstractmethod 来定义抽象方法(只能用在 metaclass 为 abc.ABCMeta 或其子类的 class 中)。<o:p></o:p>
Generic Functions。是否包含这一特性(PEP 3124 中有描述),其实还不是很确定 ,因为这个 PEP 的进展越来越慢现在几乎停滞了。希望它的步伐能够重新恢复过来。它支持基于所有参数类型的函数分派(译注:简单地说就是静态语言中的重载的动态语言版本), 而不仅仅是通常的只基于目标对象( self )的分派。<o:p></o:p>
其他重要变化<o:p></o:p>
<!---->1) <!---->异常<o:p></o:p>
字符串异常去掉了。所有异常必须继承自 BaseException ,最好是直接继承 Exception 。去掉 StandardException 。异常不再拥有序列(sequence)的行为。不过现在他们有了一个属性 args , 它就是由传给异常构造函数的参数所组成的序列。<o:p></o:p>
<!---->2) <!---->语法<o:p></o:p>
except E, e: 变成 except E as e: ,这使得语句 except E1, E2 不再导致混淆。except 子句中 as 后面的名字在退出 except 子句时会被强制移除。sys.exc_info() 变得多余了(也许会被去掉):取而代之的是 e.__class__ 是异常 类型, e.__traceback__ 是 traceback 。如果在 except 或 finally 子句中发生异常,会添加另一个可选的属性 __context__ ,其值为前一个异常对象。重抛出异常时,使用 raise E1 from E2 可以明确地设置属性 __cause__ 的值。以前的 raise 语法变种 raise E, e 和 raise E, e, tb 已经去掉了。<o:p></o:p>
<!---->3) <!---->整数<o:p></o:p>
只会有一个内置的整数类型,它就是 int ,它的行为就和 Python 2 中的 long 一样。后缀 'L' 消失。<o:p></o:p>
1/2 会返回 0.5 ,而不像以前那样返回 0 (使用 1//2 来返回 0)。表达 8 进制字面量的语法改成了 0o777 ,以免年轻程序员搞糊涂。二进制字面量:0b101 == 5, bin(5) == '0b101'。使用迭代器(Iterator)或可迭代对象(Iterable)而非列表(list)。dict.keys() 和 dict.items() 返回集合(其实是视图); dict.values() 返回一个可迭代的容器视图。 iter*() 系列消失。range() 返回以前的 xrange() 返回的对象;而 xrange() 消失。zip(), map(), filter() 返回可迭代对象(和他们在 itertools 中 对应的副本目前的行为一样)。<o:p></o:p>
<!---->4) <!---->其他<o:p></o:p>
reduce() 没了。这并不意味着我不喜欢高端函数(higher-order functions); 只不过是好像所有使用 reduce() 的代码使用原始的 for 循环重写后都便得 更可读了。不过 lambda 继续存在。倒单引号(`) 语法,通常可读性都不好,去掉了(直接使用 repr() 吧),同样 <> 操作符也 去掉了。(使用 != ,这是对 TOOWIDI 原则一个臭名昭著的违反!)<o:p></o:p>
<!---->5) <!---->标准库的革命<o:p></o:p>
关于对标准库的变化我不想说太多,因为这部分要到 3.0a1 发布之后才会开始实际的工作。而且我本人也不会去管它(语言核心就够我弄的了)。显然的是我们会除掉许多不支持了的或者 过时了的垃圾模块(比如许多模块只适用于 SGI IRIX),另外我们还在努力重命名那些以 CapWords 风格命名的模块名字,像 StringIO 或者 UserDict。<o:p></o:p>
分享到:
相关推荐
随着Python版本的更新迭代,每一次新版本的发布都会带来一些新特性或技巧,而Python 3作为当前主流版本,更是不断有新的技巧被开发和普及。以下,我们将详细讨论文中提及的Python技巧和新特性。 1. 拆箱功能...
总的来说,这个学习资源包提供了一个全面的Python学习路径,从基础知识到高级技巧,从Python 2到Python 3的新特性,应有尽有。无论是初学者还是有经验的开发者,都能从中受益匪浅。通过阅读和实践这些材料,你将能够...
python课程 连载课程 很好的老师 很好的视频 想学的赶脚的吧
这份名为"深入理解Python特性_1592298155816.pdf"的文档,显然是为了帮助读者更全面地掌握这门语言的核心特性。 首先,Python的动态类型系统是其主要特点之一。这意味着在编写代码时,我们不需要预先声明变量的类型...
根据自学总结的Python入门经验(列表特性),方便刚入门Python的同学加深理解列表的基础。
开发工具是jupyter notebook,利用matplotlib绘制发动机万有特性曲线。主要分为三部分绘制,绘制等燃油消耗曲线/等功率曲线/外特性曲线。压缩包中的图是根据实际采集到的发动机数据(出于保密,无法上传),采用多元...
Python3.9是Python语言的一次重要更新,引入了许多实用的新特性,旨在提高开发效率,增强性能,并且进一步完善了语言的语法结构。以下是对这些新特性的详细讲解: 1、字典并集和可迭代更新 在Python3.9中,字典支持...
最新版的Python通常会包含更多优化、新特性以及对旧版本的改进,旨在提供更好的开发体验。在这个"Python最新版"的压缩包中,我们看到的是Python 3.4.3的版本,这是一个稳定且广泛使用的版本。 Python 3.4.3是Python...
Python实用教程:Python基础,Python高级特性,面向对象编程,多线程,数据库,数据科学,Flask,爬虫开发教程。内部含有学习笔记、MD文档、项目教程、笔记文档 Python实用教程:Python基础,Python高级特性,面向...
001.Python介绍_特性_版本问题_应用范围 002.Python下载_安装_配置_第一行Python程序 003.开发环境介绍_交互模式的使用_IDLE介绍和使用 004.IDLE开发环境的使用_建立Python源文件
001.Python介绍_特性_版本问题_应用范围.mp4
Python 3.6是Python编程语言的一个重要版本,它在2016年12月23日正式发布,带来了许多新特性和改进。这个版本在性能、语法糖、标准库以及开发工具方面都有显著的提升,使得Python在科学计算、Web开发、数据处理等...
Python 3.12.6 是 Python 编程语言的最新版本之一,提供了众多改进和新特性,使编程体验更加高效和稳定。无论你是开发者还是数据科学家,安装 Python 3.12.6 都是提升工作效率的关键步骤。本文将为你详细介绍 Python...
在新版教程中,廖雪峰可能会更新Python的最新特性,比如Python 3.x的新特性,如非本地化字符串、asyncio模块(异步I/O)以及改进的类型注解等。此外,还可能包含当前热门的技术,如机器学习、人工智能领域的库...
在这个资料包中,我们有两个PDF文档——"深入理解Python特性_1592298155816.pdf"和"深入理解python特性pdf",它们很可能详细介绍了Python的关键特性,以及一个名为"Python源码.zip"的压缩文件,可能包含了Python的源...
Python 3.10 的主要亮点包括对语法的改进、性能优化以及新特性的引入。以下是关于这些内容的详细说明: 1. **语法改进:** - **结构化赋值(Pattern Matching)**:Python 3.10 引入了类似元组解包的新特性,允许...
Python 3.8是Python语言的一个重要版本,它包含了多个新特性和改进,旨在提升开发者的效率和代码质量。在Windows操作系统上安装Python 3.8,你需要下载对应的安装文件,如"python-3.8.8-amd64.exe",这是一个适用于...
它引入了一些重要的新特性,如异步IO支持,使得处理网络请求和其他I/O密集型任务更加高效。此外,这个版本还增强了类型注解,为静态类型检查提供了基础,但并未强制执行。Python 3.5还引入了新的语法,如async/await...