注意: 雖然 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 中的錯誤!