注意: 虽然 JavaScript 对于本网站并非必不可少,但您与内容的互动将受到限制。请开启 JavaScript 以获得完整体验。

Python 2.1[.x] 和 2.2[.x] 之间的不兼容性

<h3>Python 2.2.2 和 Python 2.2.3 之间的不兼容性</h3>

<p>Python 2.2.2 和 Python 2.2.3 之间以下可见的差异是故意的。

<ul>

<p><li>不再可能使用 object.__setattr__ 来规避
对类型对象的属性设置的限制。

<p><li>list.extend() 可以与任何可迭代对象一起使用。

<p><li>在 pdb 中,您不再可以使用负数启用断点。
数字。

<p><li>Bastion.py 和 rexec.py 模块被禁用。

<p><li>对 __class__ 赋值有一些额外的限制。

<p><li>WeakKeyDictionary 的 __delitem__ 已经改进和修复,
但可能会更改可见的行为。

</ul>

有关更多详细信息,请参见 <a href="../NEWS.txt">NEWS 文件</a>。

<h3>Python 2.1[.x] 和 Python 2.2[.x] 之间的不兼容性</h3>

<p>Python 2.2 和以前版本之间以下可见的差异是故意的。

<ul>

<p><li>此处未列出各种已弃用的模块和功能,它们可能会发出警告:这些警告不应影响程序的正确执行,并且可以使用命令行选项或以编程方式禁用;请参阅 warnings 模块的文档。

<p><li>同样未列出的是以前是错误的新的构造(例如,“key in dict” 现在是一个有效的测试,而以前总是会引发异常)。

<p><li>dir() 函数的行为与 Python 2.1 及更早版本不同。通常,dir() 返回的信息比 2.1 中返回的更多。例如,dir([]) 还报告重载各种运算符(“__add__”、“__getitem__”、“__len__”等)以及“__class__”的特殊方法。对于类(经典类和新式类),它返回该类以及基类的属性。

<p><li>不再支持特殊属性 __members__ 和 __methods__(对于大多数内置类型)。请改用新的和改进的 dir() 函数。

<p><li>type("").__name__ == "str" # 以前是 "string"

<p><li>type(0L).__name__ == "long" # 以前是 "long int"

<p><li>溢出的 int 运算返回相应的 long 值,而不是引发 OverflowError 异常。

<p><li>如果 long 值太大而无法表示为 C double,则将 long 转换为 float 现在会引发 OverflowError。这以前在大多数平台上会返回一个“无穷大”值。

<p><li>如果前两个参数中的任何一个是 float,或者如果两者都是整数类型且第二个参数为负数,则 3 参数内置 pow() 不再允许第三个非 None 参数(在后一种情况下,参数将转换为 float,所以这实际上是相同的限制)。

<p><li>一个旧的分词器错误允许使用不完整的指数的浮点文字,例如 1e 和 3.1e-。此类文字现在会引发 SyntaxError。

<p><li>嵌套作用域在 2.2 中是标准的(它们在 2.1[.1] 中通过“from __future__ import nested_scopes”按模块启用)。这可能会更改如下代码的含义

<pre>
def f(<font color="red">str</font>)
def g(x): return <font color="red">str</font>(x) return g

系统消息:警告/2 (<string>, 第 84 行)

定义列表在没有空白行的情况下结束;意外的取消缩进。

</pre>

在此示例中,内部函数 g() 中 <font color="red">str</font> 的使用现在是指外部函数 f() 中的参数 <font color="red">str</font>;以前(没有嵌套作用域),它会引用内置函数 <font color="blue">str</font>。

<p><li>未绑定的方法对象以不同的方式设置其 im_class 字段。在以前的版本中,im_class 字段设置为<i>定义</i>该方法的类。现在,它设置为用于创建方法对象的类。例如

<pre>
class A
def meth(self): ...
class B(A)
... # 没有定义 meth
class C(A)
def meth(self)
B.meth(self) # 错误,C 不继承自 B

系统消息:警告/2 (<string>, 第 105 行)

定义列表在没有空白行的情况下结束;意外的取消缩进。

</pre>

此代码以前可以意外工作,即使 B 不是 C 的基类,因为 B.meth.im_class 设置为 A,并且 A 是 C 的基类!据推测,很久以前继承树是不同的,C 确实继承自 B;当更改时,向上调用没有修复。当不相关的类 B 获得 meth() 的新定义时,C 将会崩溃。此外,以前,B().meth.im_class 将返回 A;现在它返回 B(因为它是一个绑定到 B 实例的方法)。

<p><li>GC 模块的 C API 发生了不兼容的更改。编写为支持 GC 模块的 2.1 版本的扩展仍然可以编译,但 GC 功能将被禁用。

<p><li>gc.garbage 的内容不同;它以前包含所有不可收集的循环;现在它仅包含具有 __del__ 方法的不可收集循环中的对象。

<p><li>字典项的哈希顺序与以前的版本不同。(任何代码都不应依赖此顺序,但很容易忘记这一点。)

<p><li>在编译时,对 __debug__ 的赋值会引发 SyntaxError。

<p><li>UTF-16 编解码器已修改为更符合 RFC。它现在只会在字符串的开头删除 BOM 字符,并且仅在以本机模式运行时删除(UTF-16-LE 和 -BE 不会删除前导 BMO 字符)。

<p><li>许多错误消息是不同的;在某些情况下,错误情况会引发不同的异常(最常见的是 TypeError 和 AttributeError 交换的情况)。

</ul>

<h3>经典类和新式类之间的差异</h3>

<p>当您将经典类转换为新式类时,以下经典类和新式类之间的差异可能需要注意。由于 Python 的先前版本不支持新式类,因此这些不能被认为是真正的错误,但是由于我们已尽力使新式类的行为向后兼容,因此请务必注意这些差异。(当然,如果您从头开始编写一个新式类,那么会有更多差异变得相关;此列表仅列出与经典类的转换相关的行为更改。)

<ul>

<p><li>方法解析顺序是不同的;请参阅 <a href="../descrintro/#mro">教程</a>。

<p><li>重载二元运算符(__add__ 等)的新式类不能依赖 __coerce__ 方法来强制转换参数;另一个参数将是最初存在的任何值。因此,如果 x 是一个定义了 __add__ 方法的新式类实例,则 x+1 会调用 x.__add__(1)。方法实现将必须分析另一个参数的类型,以便能够正确地实现操作。如果方法实现决定它不知道如何为这种特定的参数类型组合实现该操作,则它应返回特殊的单例值 NotImplemented。(此行为与缺少 __coerce__ 方法的经典类的行为相同;不同之处在于新式二元运算符会忽略 __coerce__ 方法。)

<p><li>仅当旧类和新类的 C 级结构布局相同时,新式类实例才允许对其 __class__ 属性进行赋值。这可以防止诸如获取列表并更改其 __class__ 以使其成为字典之类的灾难。

<p><li>新式类对象不支持对其 __bases__ 属性进行赋值。

<p><li>新式类对象不支持对其 __name__ 属性进行赋值。

<p><li>(我确定还有更多与将经典类转换为新式类相关的差异),但我现在想不起来了。)

</ul>

<p>要报告上面未列出的错误,请始终使用 SourceForge <a href="http://sourceforge.net/bugs/?group_id=5470">Bug Tracker</a>。如果您有补丁,请使用 SourceForge <a href="http://sourceforge.net/patch/?group_id=5470">Patch Manager</a>。请注明您正在报告 2.2.3 中的错误!