Python 2.4 新特性

作者:

A.M. Kuchling

本文解釋了 Python 2.4.1(2005 年 3 月 30 日釋出)中的新特性。

Python 2.4 是一箇中等規模的版本。它不像激進的 Python 2.2 那樣引入了大量變化,但比保守的 2.3 版本引入了更多功能。最重要的新語言特性是函式裝飾器和生成器表示式;其他大部分變化都在標準庫中。

根據 CVS 更改日誌,Python 2.3 和 2.4 之間應用了 481 個補丁,修復了 502 個錯誤。這兩個數字可能都被低估了。

本文不試圖提供每個新功能的完整規範,而是對每個功能進行簡要介紹。要了解完整詳細資訊,請參閱 Python 2.4 的文件,例如 Python 庫參考和 Python 參考手冊。通常,您會被引導到特定新功能的 PEP,以瞭解其實現和設計原理。

PEP 218:內建集合物件

Python 2.3 引入了 sets 模組。集合資料型別的 C 實現現已作為兩個新的內建型別 set(iterable)frozenset(iterable) 新增到 Python 核心中。它們為成員測試、從序列中消除重複項以及並集、交集、差集和對稱差集等數學運算提供了高速操作。

>>> a = set('abracadabra')              # form a set from a string
>>> 'z' in a                            # fast membership testing
False
>>> a                                   # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a)                          # convert back into a string
'arbcd'

>>> b = set('alacazam')                 # form a second set
>>> a - b                               # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b                               # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                               # letters in both a and b
set(['a', 'c'])
>>> a ^ b                               # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])

>>> a.add('z')                          # add a new element
>>> a.update('wxy')                     # add multiple new elements
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x')                       # take one element out
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

frozenset() 型別是 set() 的不可變版本。由於它是不可變且可雜湊的,因此可以用作字典鍵或另一個集合的成員。

sets 模組保留在標準庫中,如果您希望對 SetImmutableSet 類進行子類化,它可能會很有用。目前沒有計劃棄用該模組。

參見

PEP 218 - 新增內建集合物件型別

最初由 Greg Wilson 提出,最終由 Raymond Hettinger 實現。

PEP 237:統一長整數和整數

這項 PEP 的漫長過渡過程始於 Python 2.2,在 Python 2.4 中又向前邁進了一步。在 2.3 中,某些在 int/long 統一後行為會有所不同的整數操作會觸發 FutureWarning 警告並返回限制為 32 或 64 位(取決於您的平臺)的值。在 2.4 中,這些表示式不再產生警告,而是產生一個不同的結果,通常是一個長整數。

有問題​​的表示式主要是左移和冗長的十六進位制和八進位制常量。例如,2 << 32 在 2.3 中會導致警告,在 32 位平臺上評估為 0。在 Python 2.4 中,此表示式現在返回正確答案 8589934592。

參見

PEP 237 - 統一長整數和整數

原始 PEP 由 Moshe Zadka 和 GvR 撰寫。2.4 的更改由 Kalle Svensson 實現。

PEP 289:生成器表示式

Python 2.2 中引入的迭代器功能和 itertools 模組使得編寫程式更容易遍歷大型資料集,而無需一次性將整個資料集載入到記憶體中。列表推導式在這種情況下表現不佳,因為它們會生成一個包含所有項的 Python 列表物件。這不可避免地會將所有物件載入到記憶體中,如果資料集非常大,這可能會成為問題。在嘗試編寫函式式風格的程式時,自然會寫出類似以下的程式碼:

links = [link for link in get_all_links() if not link.followed]
for link in links:
    ...

而不是

for link in get_all_links():
    if link.followed:
        continue
    ...

第一種形式更簡潔,可能更具可讀性,但如果您處理大量連結物件,則必須編寫第二種形式以避免所有連結物件同時存在於記憶體中。

生成器表示式的工作方式類似於列表推導式,但不會具體化整個列表;相反,它們會建立一個生成器,一個接一個地返回元素。上面的例子可以寫成

links = (link for link in get_all_links() if not link.followed)
for link in links:
    ...

生成器表示式總是必須寫在括號內,如上面的例子所示。表示函式呼叫的括號也算數,所以如果你想建立一個將立即傳遞給函式的迭代器,你可以寫

print sum(obj.count for obj in list_all_objects())

生成器表示式與列表推導式在各種細微之處有所不同。最值得注意的是,迴圈變數(在上面的例子中是 obj)在生成器表示式之外無法訪問。列表推導式將變數分配給其最後一個值;Python 的未來版本將改變這一點,使列表推導式在這方面與生成器表示式匹配。

參見

PEP 289 - 生成器表示式

由 Raymond Hettinger 提出,Jiwon Seo 實現,Hye-Shik Chang 早期指導。

PEP 292:更簡單的字串替換

標準庫中的一些新類提供了另一種將變數替換到字串中的機制;這種替換方式可能更適合需要非專業使用者編輯模板的應用程式。

按名稱替換變數的常用方法是 % 運算子

>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'

在編寫模板字串時,很容易忘記右括號後的 is。如果模板在 Python 模組中,這並不是一個大問題,因為您執行程式碼,得到一個“不支援的格式字元”ValueError,然後修復問題。但是,考慮像 Mailman 這樣的應用程式,其中模板字串或翻譯由不瞭解 Python 語言的使用者編輯。格式字串的語法對於這些使用者來說解釋起來很複雜,如果他們犯了錯誤,很難向他們提供有用的反饋。

PEP 292 將 Template 類新增到 string 模組中,該類使用 $ 來指示替換

>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'

如果字典中缺少鍵,substitute() 方法將引發 KeyError。還有一個 safe_substitute() 方法,它忽略缺少的鍵

>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'

參見

PEP 292 - 更簡單的字串替換

由 Barry Warsaw 編寫和實現。

PEP 318:函式和方法的裝飾器

Python 2.2 透過新增靜態方法和類方法擴充套件了 Python 的物件模型,但它沒有擴充套件 Python 的語法來提供任何定義靜態或類方法的新方式。相反,您必須像往常一樣編寫 def 語句,並將生成的方法傳遞給 staticmethod()classmethod() 函式,該函式會將該函式包裝為新型別的方法。您的程式碼看起來像這樣

class C:
   def meth (cls):
       ...

   meth = classmethod(meth)   # Rebind name to wrapped-up class method

如果方法很長,很容易錯過或忘記函式體後面的 classmethod() 呼叫。

最初的意圖是新增一些語法來使此類定義更具可讀性,但在 2.2 釋出時,好的語法並不明顯。今天好的語法 仍然 不明顯,但使用者要求更輕鬆地訪問該功能;已經添加了一個新的語法功能來滿足這一需求。

新功能稱為“函式裝飾器”。這個名字來源於這樣的想法:classmethod()staticmethod() 和類似函式正在函式物件上儲存額外資訊;它們正在用更多細節“裝飾”函式。

該符號借鑑了 Java,並使用 '@' 字元作為指示符。使用新語法,上面的示例將寫成

class C:

   @classmethod
   def meth (cls):
       ...

@classmethodmeth=classmethod(meth) 賦值的縮寫。更一般地,如果你有以下程式碼

@A
@B
@C
def f ():
    ...

它等價於以下裝飾器前的程式碼

def f(): ...
f = A(B(C(f)))

裝飾器必須在函式定義之前的行上,每行一個裝飾器,並且不能與 def 語句在同一行,這意味著 @A def f(): ... 是非法的。您只能裝飾函式定義,無論是在模組級別還是在類內部;您不能裝飾類定義。

裝飾器只是一個函式,它以要裝飾的函式作為引數,並返回相同的函式或一些新物件。裝飾器的返回值不需要是可呼叫的(儘管通常是),除非進一步的裝飾器將應用於結果。編寫自己的裝飾器很容易。以下簡單示例只在函式物件上設定一個屬性

>>> def deco(func):
...    func.attr = 'decorated'
...    return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>

作為一個稍微更現實的例子,以下裝飾器檢查提供的引數是否為整數

def require_int (func):
    def wrapper (arg):
        assert isinstance(arg, int)
        return func(arg)

    return wrapper

@require_int
def p1 (arg):
    print arg

@require_int
def p2(arg):
    print arg*2

PEP 318 中的一個例子包含了這種思想的一個更高階的版本,它允許您同時指定所需的型別並檢查返回的型別。

裝飾器函式可以接受引數。如果提供了引數,您的裝飾器函式將僅使用這些引數被呼叫,並且必須返回一個新的裝飾器函式;此函式必須接受一個函式並返回一個函式,如前所述。換句話說,@A @B @C(args) 變為

def f(): ...
_deco = C(args)
f = A(B(_deco(f)))

正確理解這一點可能有點費腦,但也不是太難。

一個相關的微小變化使函式的 func_name 屬性可寫。此屬性用於在回溯中顯示函式名稱,因此裝飾器應更改構造並返回的任何新函式的名稱。

參見

PEP 318 - 函式、方法和類的裝飾器

由 Kevin D. Smith、Jim Jewett 和 Skip Montanaro 撰寫。幾個人編寫了實現函式裝飾器的補丁,但實際簽入的是 Mark Russell 編寫的補丁 #979728。

https://wiki.python.org/moin/PythonDecoratorLibrary

此 Wiki 頁面包含幾個裝飾器的示例。

PEP 322:反向迭代

一個新的內建函式 reversed(seq),它接受一個序列並返回一個以相反順序遍歷序列元素的迭代器。

>>> for i in reversed(xrange(1,4)):
...    print i
...
3
2
1

與擴充套件切片(例如 range(1,4)[::-1])相比,reversed() 更易讀,執行速度更快,並且使用的記憶體明顯更少。

請注意,reversed() 只接受序列,不接受任意迭代器。如果您想反轉迭代器,請先使用 list() 將其轉換為列表。

>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
...   print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
  ...

參見

PEP 322 - 反向迭代

由 Raymond Hettinger 編寫和實現。

PEP 324:新 subprocess 模組

標準庫提供了多種執行子程序的方法,提供了不同的功能和不同級別的複雜性。 os.system(command) 易於使用,但速度慢(它執行一個執行命令的 shell 程序)且危險(您必須小心轉義 shell 的元字元)。 popen2 模組提供了可以從子程序捕獲標準輸出和標準錯誤的類,但命名令人困惑。 subprocess 模組解決了這個問題,提供了一個統一的介面,提供您可能需要的所有功能。

popen2 的類集合不同,subprocess 包含一個名為 subprocess.Popen 的單個類,其建構函式支援許多不同的關鍵字引數。

class Popen(args, bufsize=0, executable=None,
            stdin=None, stdout=None, stderr=None,
            preexec_fn=None, close_fds=False, shell=False,
            cwd=None, env=None, universal_newlines=False,
            startupinfo=None, creationflags=0):

args 通常是字串序列,將作為執行的子程序的引數。(如果 shell 引數為真,args 可以是一個字串,然後會傳遞給 shell 進行解釋,就像 os.system() 所做的那樣。)

stdinstdoutstderr 指定子程序的輸入、輸出和錯誤流。您可以提供檔案物件或檔案描述符,也可以使用常量 subprocess.PIPE 在子程序和父程序之間建立管道。

建構函式有許多便捷選項

  • close_fds 請求在執行子程序之前關閉所有檔案描述符。

  • cwd 指定子程序將執行的工作目錄(預設為父程序的工作目錄)。

  • env 是一個指定環境變數的字典。

  • preexec_fn 是在子程序啟動之前呼叫的函式。

  • universal_newlines 使用 Python 的通用換行符功能開啟子程序的輸入和輸出。

建立 Popen 例項後,您可以呼叫其 wait() 方法暫停直到子程序退出,呼叫 poll() 檢查它是否退出而無需暫停,或者呼叫 communicate(data) 將字串 data 傳送到子程序的標準輸入。然後 communicate(data) 讀取子程序已傳送到其標準輸出或標準錯誤的任何資料,返回一個元組 (stdout_data, stderr_data)

call() 是一個快捷方式,它將其引數傳遞給 Popen 建構函式,等待命令完成,並返回子程序的狀態碼。它可以作為 os.system() 的更安全的替代品

sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
    # Success
    ...
else:
    # dpkg returned an error
    ...

命令在不使用 shell 的情況下被呼叫。如果你真的想使用 shell,你可以新增 shell=True 作為關鍵字引數並提供一個字串而不是序列

sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)

PEP 舉了幾個 shell 和 Python 程式碼的例子,並展示瞭如何將它們轉換為使用 subprocess 的 Python 程式碼。強烈建議閱讀 PEP 的這一部分。

參見

PEP 324 - subprocess - 新程序模組

由 Peter Åstrand 編寫和實現,並得到了 Fredrik Lundh 等人的協助。

PEP 327:Decimal 資料型別

Python 始終支援基於底層 C double 型別的浮點 (FP) 數字作為資料型別。然而,雖然大多數程式語言都提供了浮點型別,但許多人(甚至是程式設計師)都沒有意識到浮點數不能準確表示某些十進位制分數。新的 Decimal 型別可以準確表示這些分數,精度限制由使用者指定。

為什麼需要 Decimal?

這些限制源於浮點數使用的表示。浮點數由三個元件組成

  • 符號,正或負。

  • 尾數,一個單數字二進位制數,後跟小數部分。例如,基數 2 記法中的 1.011 + 0/2 + 1/4,或十進位制記法中的 1.25。

  • 指數,表示所表示數字中小數點的位置。

例如,數字 1.25 具有正號,尾數值為 1.01(二進位制),指數為 0(小數點不需要移動)。數字 5 具有相同的符號和尾數,但指數為 2,因為尾數乘以 4(2 的指數 2 次方);1.25 * 4 等於 5。

現代系統通常提供符合名為 IEEE 754 標準的浮點支援。C 的 double 型別通常實現為 64 位 IEEE 754 數字,它使用 52 位空間作為尾數。這意味著數字只能指定到 52 位精度。如果您嘗試表示無限重複的數字,則展開將在 52 位後截斷。不幸的是,大多數軟體需要以 10 為基數生成輸出,而以 10 為基數的常見分數在二進位制中通常是重複小數。例如,十進位制 1.1 是二進位制 1.0001100110011 ...;.1 = 1/16 + 1/32 + 1/256 加上無限多個附加項。IEEE 754 必須在 52 位後截斷無限重複的小數,因此表示略有不準確。

有時在列印數字時可以看到這種不準確

>>> 1.1
1.1000000000000001

當您列印數字時,不準確性並不總是可見的,因為浮點數到十進位制字串的轉換由 C 庫提供,大多數 C 庫都嘗試生成合理的輸出。但是,即使不顯示,不準確性仍然存在,後續操作可能會放大錯誤。

對於許多應用程式來說,這並不重要。如果我正在繪製點並將其顯示在顯示器上,則 1.1 和 1.1000000000000001 之間的差異太小而無法看到。報告通常將輸出限制在一定數量的小數位,如果您將數字四捨五入到兩位或三位甚至八位小數,則錯誤永遠不會顯現。但是,對於重要的應用程式,實現自己的自定義算術例程需要大量工作。

因此,建立了 Decimal 型別。

Decimal 型別

一個新的模組 decimal 已新增到 Python 的標準庫中。它包含兩個類:DecimalContextDecimal 例項表示數字,Context 例項用於封裝各種設定,例如精度和預設舍入模式。

Decimal 例項是不可變的,就像普通的 Python 整數和浮點數一樣;一旦建立,您就無法更改例項表示的值。Decimal 例項可以從整數或字串建立

>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")

您還可以提供包含符號、表示為十進位制數字元組的尾數和指數的元組

>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")

注意:符號位是布林值,所以 0 是正數,1 是負數。

從浮點數轉換會帶來一些問題:表示 1.1 的浮點數應該轉換為精確的十進位制數 1.1,還是轉換為 1.1 加上引入的任何不準確性?決定是迴避這個問題,並將這種轉換排除在 API 之外。相反,您應該使用所需的精度將浮點數轉換為字串,並將字串傳遞給 Decimal 建構函式

>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")

一旦您擁有 Decimal 例項,就可以對它們執行常見的數學運算。一個限制:冪運算需要整數指數

>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
  ...
decimal.InvalidOperation: x ** (non-integer)

您可以將 Decimal 例項與整數組合,但不能與浮點數組合

>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
  ...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>

Decimal 數字可以與 mathcmath 模組一起使用,但請注意,在執行操作之前,它們會立即轉換為浮點數,這可能會導致精度和準確性損失。您還將獲得一個普通的浮點數,而不是 Decimal

>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j

Decimal 例項有一個 sqrt() 方法,它返回一個 Decimal,但是如果你需要其他東西,例如三角函式,你將不得不自己實現它們。

>>> d.sqrt()
Decimal("351364.1828820134592177245001")

Context 型別

Context 類的例項封裝了十進位制運算的多個設定

  • prec 是精度,即小數位數。

  • rounding 指定舍入模式。decimal 模組有各種可能性的常量:ROUND_DOWNROUND_CEILINGROUND_HALF_EVEN 和其他各種常量。

  • traps 是一個字典,指定在遇到某些錯誤條件時會發生什麼:要麼引發異常,要麼返回一個值。錯誤條件的一些示例是除零、精度丟失和溢位。

透過呼叫 getcontext() 可以獲得一個執行緒本地的預設上下文;您可以更改此上下文的屬性以更改預設精度、舍入或陷阱處理。以下示例顯示了更改預設上下文精度的效果

>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")

錯誤條件的預設操作是可選的;模組可以返回一個特殊值,例如無窮大或非數字,或者可以引發異常

>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
  ...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>

Context 例項還具有用於格式化數字的各種方法,例如 to_eng_string()to_sci_string()

有關更多資訊,請參閱 decimal 模組的文件,其中包括快速入門教程和參考。

參見

PEP 327 - Decimal 資料型別

由 Facundo Batista 撰寫,並由 Facundo Batista、Eric Price、Raymond Hettinger、Aahz 和 Tim Peters 實現。

http://www.lahey.com/float.htm

本文使用 Fortran 程式碼來說明浮點不準確可能導致的許多問題。

https://speleotrove.com/decimal/

對基於十進位制表示的描述。這種表示正在被提議為標準,並且是新的 Python 十進位制型別的基礎。大部分材料由 Rexx 語言的設計者 Mike Cowlishaw 撰寫。

PEP 328:多行匯入

一個語言變化是一個小的語法調整,旨在使從模組匯入多個名稱變得更容易。在 from module import names 語句中,names 是一個逗號分隔的名稱序列。如果序列很長,您可以從同一個模組匯入多個,或者可以使用反斜槓轉義行尾,如下所示

from SimpleXMLRPCServer import SimpleXMLRPCServer,\
            SimpleXMLRPCRequestHandler,\
            CGIXMLRPCRequestHandler,\
            resolve_dotted_attribute

Python 2.4 中的語法更改只是允許將名稱放在括號中。Python 忽略括號內的換行符,因此不再需要反斜槓

from SimpleXMLRPCServer import (SimpleXMLRPCServer,
                                SimpleXMLRPCRequestHandler,
                                CGIXMLRPCRequestHandler,
                                resolve_dotted_attribute)

PEP 還提議所有 import 語句都是絕對匯入,以一個前導 . 字元表示相對匯入。PEP 的這部分內容沒有在 Python 2.4 中實現,但在 Python 2.5 中完成了。

參見

PEP 328 - Imports: Multi-Line and Absolute/Relative

由 Aahz 撰寫。多行匯入由 Dima Dorfman 實現。

PEP 331:獨立於區域設定的浮點/字串轉換

locale 模組允許 Python 軟體選擇各種本地化到特定國家或語言的轉換和顯示約定。但是,該模組小心地不更改數字區域設定,因為 Python 實現中的各種函式要求數字區域設定保持設定為 'C' 區域設定。通常這是因為程式碼使用了 C 庫的 atof() 函式。

但是,不設定數字區域設定給使用第三方 C 庫的擴充套件帶來了麻煩,因為它們沒有設定正確的區域設定。激勵性的例子是 GTK+,它的使用者介面小部件沒有以當前區域設定顯示數字。

PEP 中描述的解決方案是向 Python API 新增三個執行僅 ASCII 轉換的新函式,忽略區域設定

  • PyOS_ascii_strtod(str, ptr)PyOS_ascii_atof(str, ptr) 都將字串轉換為 C double

  • PyOS_ascii_formatd(buffer, buf_len, format, d) 將一個 double 轉換為 ASCII 字串。

這些函式的程式碼來自 GLib 庫(https://developer-old.gnome.org/glib/2.26/),其開發者慷慨地重新許可了相關函式並將其捐贈給 Python 軟體基金會。locale 模組現在可以更改數字區域設定,從而允許 GTK+ 等擴充套件產生正確的結果。

參見

PEP 331 - 獨立於區域設定的浮點/字串轉換

由 Christian R. Reis 撰寫,Gustavo Carneiro 實現。

其他語言更改

以下是 Python 2.4 對核心 Python 語言的所有更改。

  • 添加了函式和方法的裝飾器(PEP 318)。

  • 添加了內建的 set()frozenset() 型別(PEP 218)。其他新的內建函式包括 reversed(seq) 函式(PEP 322)。

  • 添加了生成器表示式(PEP 289)。

  • 某些數值表示式不再返回限制為 32 位或 64 位的值(PEP 237)。

  • 現在可以在 from module import names 語句中,在名稱列表周圍加上括號(PEP 328)。

  • dict.update() 方法現在接受與 dict 建構函式相同的引數形式。這包括任何對映、任何鍵/值對的可迭代物件以及關鍵字引數。(由 Raymond Hettinger 貢獻。)

  • 字串方法 ljust()rjust()center() 現在接受一個可選引數,用於指定除空格以外的填充字元。(由 Raymond Hettinger 貢獻。)

  • 字串還新增了 rsplit() 方法,其功能與 split() 方法類似,但從字串末尾開始拆分。(由 Sean Reifschneider 貢獻。)

    >>> 'www.python.org'.split('.', 1)
    ['www', 'python.org']
    'www.python.org'.rsplit('.', 1)
    ['www.python', 'org']
    
  • 列表的 sort() 方法增加了三個關鍵字引數:cmpkeyreverse。這些引數使 sort() 的一些常見用法更簡單。所有這些引數都是可選的。

    對於 cmp 引數,其值應該是一個比較函式,該函式接受兩個引數並根據它們的比較結果返回 -1、0 或 +1。然後將使用此函式對列表進行排序。以前,這是唯一可以提供給 sort() 的引數。

    key 應該是一個單引數函式,它接受一個列表元素並返回該元素的比較鍵。然後使用比較鍵對列表進行排序。以下示例對列表進行不區分大小寫的排序

    >>> L = ['A', 'b', 'c', 'D']
    >>> L.sort()                 # Case-sensitive sort
    >>> L
    ['A', 'D', 'b', 'c']
    >>> # Using 'key' parameter to sort list
    >>> L.sort(key=lambda x: x.lower())
    >>> L
    ['A', 'b', 'c', 'D']
    >>> # Old-fashioned way
    >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
    >>> L
    ['A', 'b', 'c', 'D']
    

    最後一個示例使用 cmp 引數,是執行不區分大小寫排序的舊方法。它有效但比使用 key 引數慢。使用 key 為列表中的每個元素呼叫一次 lower() 方法,而使用 cmp 將為每次比較呼叫兩次,因此使用 key 可以節省 lower() 方法的呼叫次數。

    對於簡單的鍵函式和比較函式,通常可以透過使用非繫結方法來避免 lambda 表示式。例如,上述不區分大小寫的排序最好寫成

    >>> L.sort(key=str.lower)
    >>> L
    ['A', 'b', 'c', 'D']
    

    最後,reverse 引數接受一個布林值。如果該值為真,則列表將按相反順序排序。現在,您可以編寫 L.sort(reverse=True) 而不是 L.sort(); L.reverse()

    排序結果現在保證是穩定的。這意味著具有相同鍵的兩個條目將按照它們輸入的相同順序返回。例如,您可以按名稱對人員列表進行排序,然後按年齡對列表進行排序,從而得到一個按年齡排序的列表,其中年齡相同的人員按名稱排序。

    (對 sort() 的所有更改均由 Raymond Hettinger 貢獻。)

  • 新增了一個內建函式 sorted(iterable),它的工作方式與原地 list.sort() 方法類似,但可以在表示式中使用。區別在於

  • 輸入可以是任何可迭代物件;

  • 對新形成的副本進行排序,保持原始副本不變;並且

  • 表示式返回新的已排序副本

    >>> L = [9,7,8,3,2,4,1,6,5]
    >>> [10+i for i in sorted(L)]       # usable in a list comprehension
    [11, 12, 13, 14, 15, 16, 17, 18, 19]
    >>> L                               # original is left unchanged
    [9,7,8,3,2,4,1,6,5]
    >>> sorted('Monty Python')          # any iterable may be an input
    [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']
    
    >>> # List the contents of a dict sorted by key values
    >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
    >>> for k, v in sorted(colormap.iteritems()):
    ...     print k, v
    ...
    black 4
    blue 2
    green 3
    red 1
    yellow 5
    

    (由 Raymond Hettinger 貢獻。)

  • 整數操作將不再觸發 OverflowWarningOverflowWarning 警告將在 Python 2.5 中消失。

  • 直譯器新增了一個開關 -m,它接受一個名稱,在 sys.path 中搜索相應的模組,並將該模組作為指令碼執行。例如,您現在可以使用 python -m profile 執行 Python 分析器。(由 Nick Coghlan 貢獻。)

  • eval(expr, globals, locals)execfile(filename, globals, locals) 函式以及 exec 語句現在接受任何對映型別作為 locals 引數。以前這必須是常規的 Python 字典。(由 Raymond Hettinger 貢獻。)

  • 內建函式 zip()itertools.izip() 在不帶引數呼叫時現在返回一個空列表。以前它們會引發 TypeError 異常。這使得它們更適合與可變長度引數列表一起使用

    >>> def transpose(array):
    ...    return zip(*array)
    ...
    >>> transpose([(1,2,3), (4,5,6)])
    [(1, 4), (2, 5), (3, 6)]
    >>> transpose([])
    []
    

    (由 Raymond Hettinger 貢獻。)

  • 在匯入模組時遇到故障不再會在 sys.modules 中留下部分初始化的模組物件。留下不完整的模組物件會欺騙後續匯入同一模組的操作成功,從而導致令人困惑的錯誤。(由 Tim Peters 修復。)

  • None 現在是一個常量;將新值繫結到名稱 None 的程式碼現在是語法錯誤。(由 Raymond Hettinger 貢獻。)

最佳化

  • 列表和元組切片的內部迴圈經過最佳化,現在執行速度提高了約三分之一。字典的內部迴圈也經過最佳化,從而提高了 keys()values()items()iterkeys()itervalues()iteritems() 的效能。(由 Raymond Hettinger 貢獻。)

  • 列表增長和收縮的機制已針對速度和空間效率進行了最佳化。由於更高效的程式碼路徑和更少使用底層系統 realloc(),從列表中新增和彈出元素現在執行速度更快。列表推導式也受益。list.extend() 也得到了最佳化,不再在其引數轉換為臨時列表後才擴充套件基本列表。(由 Raymond Hettinger 貢獻。)

  • list()tuple()map()filter()zip() 在使用提供 __len__() 方法的非序列引數時,現在執行速度提高了數倍。(由 Raymond Hettinger 貢獻。)

  • 方法 list.__getitem__()dict.__getitem__()dict.__contains__() 現在實現為 method_descriptor 物件,而不是 wrapper_descriptor 物件。這種形式的訪問使它們的效能翻倍,並使它們更適合用作函式式引數:map(mydict.__getitem__, keylist)。(由 Raymond Hettinger 貢獻。)

  • 新增了一個操作碼 LIST_APPEND,它簡化了列表推導式生成的位元組碼,並將其速度提高了約三分之一。(由 Raymond Hettinger 貢獻。)

  • 窺孔位元組碼最佳化器已得到改進,可生成更短、更快的位元組碼;值得注意的是,生成的位元組碼更具可讀性。(由 Raymond Hettinger 增強。)

  • 形式為 s = s + "abc"s += "abc" 的字串連線在某些情況下現在執行效率更高。此最佳化不會出現在其他 Python 實現中,例如 Jython,因此您不應依賴它;當您希望高效地將大量字串粘合在一起時,仍然建議使用字串的 join() 方法。(由 Armin Rigo 貢獻。)

2.4 最佳化的最終結果是 Python 2.4 執行 pystone 基準測試的速度比 Python 2.3 快約 5%,比 Python 2.2 快 35%。(pystone 不是一個特別好的基準測試,但它是最常用的 Python 效能衡量標準。您自己的應用程式可能從 Python 2.4 中獲得更大或更小的收益。)

新的、改進的和已棄用的模組

一如既往,Python 的標準庫獲得了許多增強和錯誤修復。以下是一些最顯著變化的區域性列表,按模組名稱按字母順序排序。有關更完整的更改列表,請查閱原始碼樹中的 Misc/NEWS 檔案,或檢視 CVS 日誌以獲取所有詳細資訊。

  • asyncore 模組的 loop() 函式現在有一個 count 引數,允許您執行有限次數的輪詢迴圈。預設仍然是無限迴圈。

  • base64 模組現在更完整地支援 RFC 3548 中的 Base64、Base32 和 Base16 編碼和解碼,包括可選的大小寫摺疊和可選的替代字母表。(由 Barry Warsaw 貢獻。)

  • bisect 模組現在有了底層的 C 實現,以提高效能。(由 Dmitry Vasiliev 貢獻。)

  • 由 Hye-Shik Chang 維護的 CJKCodecs 東亞編碼集合已整合到 2.4 中。新的編碼包括

  • 中文(中華人民共和國):gb2312、gbk、gb18030、big5hkscs、hz

  • 中文(中華民國):big5、cp950

  • 日文:cp932、euc-jis-2004、euc-jp、euc-jisx0213、iso-2022-jp、

    iso-2022-jp-1、iso-2022-jp-2、iso-2022-jp-3、iso-2022-jp-ext、iso-2022-jp-2004、shift-jis、shift-jisx0213、shift-jis-2004

  • 韓文:cp949、euc-kr、johab、iso-2022-kr

  • 還添加了一些其他新編碼:HP Roman8、ISO_8859-11、ISO_8859-16、PCTP-154 和 TIS-620。

  • UTF-8 和 UTF-16 編解碼器現在能更好地處理接收部分輸入。以前,StreamReader 類會嘗試讀取更多資料,使得從流恢復解碼變得不可能。read() 方法現在將返回儘可能多的資料,並且未來的呼叫將從上次停止的地方恢復解碼。(由 Walter Dörwald 實現。)

  • 新增了一個 collections 模組,用於各種專門的集合資料型別。目前它只包含一種型別 deque,一個雙端佇列,支援高效地從兩端新增和刪除元素

    >>> from collections import deque
    >>> d = deque('ghi')        # make a new deque with three items
    >>> d.append('j')           # add a new entry to the right side
    >>> d.appendleft('f')       # add a new entry to the left side
    >>> d                       # show the representation of the deque
    deque(['f', 'g', 'h', 'i', 'j'])
    >>> d.pop()                 # return and remove the rightmost item
    'j'
    >>> d.popleft()             # return and remove the leftmost item
    'f'
    >>> list(d)                 # list the contents of the deque
    ['g', 'h', 'i']
    >>> 'h' in d                # search the deque
    True
    

    現在,Queuethreading 等幾個模組利用 collections.deque 來提高效能。(由 Raymond Hettinger 貢獻。)

  • ConfigParser 類得到了一些增強。read() 方法現在返回成功解析的檔案列表,如果傳遞的 value 引數不是字串,set() 方法會引發 TypeError。(由 John Belmonte 和 David Goodger 貢獻。)

  • curses 模組現在支援 ncurses 擴充套件 use_default_colors()。在終端支援透明度的平臺上,這使得可以使用透明背景。(由 Jörg Lehmann 貢獻。)

  • difflib 模組現在包含一個 HtmlDiff 類,該類建立一個 HTML 表格,並排顯示文字的兩個版本。(由 Dan Gass 貢獻。)

  • email 包已更新到版本 3.0,該版本放棄了各種已棄用的 API,並取消了對 2.3 之前 Python 版本的支援。該包的 3.0 版本使用了一種新的增量 MIME 訊息解析器,可在 email.FeedParser 模組中找到。新解析器不需要將整個訊息讀入記憶體,並且如果訊息格式不正確也不會引發異常;相反,它會將任何問題記錄在訊息的 defect 屬性中。(由 Anthony Baxter、Barry Warsaw、Thomas Wouters 等人開發。)

  • heapq 模組已轉換為 C 語言。由此帶來的十倍速度提升使得該模組適用於處理大量資料。此外,該模組還有兩個新函式 nlargest()nsmallest(),它們使用堆在不完全排序的情況下查詢資料集中最大的 N 個值或最小的 N 個值。(由 Raymond Hettinger 貢獻。)

  • httplib 模組現在包含各種與 HTTP 相關的 RFC 文件中定義的 HTTP 狀態碼常量。常量名稱包括 OKCREATEDCONTINUEMOVED_PERMANENTLY;使用 pydoc 獲取完整列表。(由 Andrew Eland 貢獻。)

  • imaplib 模組現在支援 IMAP 的 THREAD 命令(由 Yves Dionne 貢獻)以及新的 deleteacl()myrights() 方法(由 Arnaud Mazin 貢獻)。

  • itertools 模組新增了 groupby(iterable[, *func*]) 函式。iterable 是可以迭代以返回元素流的物件,可選的 func 引數是一個函式,它接受一個元素並返回一個鍵值;如果省略,則鍵就是元素本身。groupby() 然後將元素分組為具有匹配鍵值的子序列,並返回一系列包含鍵值和子序列迭代器的 2 元組。

    下面是一個例子,使其更清晰。key 函式只是簡單地返回一個數字是奇數還是偶數,因此 groupby() 的結果是返回連續的奇數或偶數序列。

    >>> import itertools
    >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
    >>> for key_val, it in itertools.groupby(L, lambda x: x % 2):
    ...    print key_val, list(it)
    ...
    0 [2, 4, 6]
    1 [7]
    0 [8]
    1 [9, 11]
    0 [12, 14]
    >>>
    

    groupby() 通常與已排序的輸入一起使用。groupby() 的邏輯類似於 Unix 的 uniq 過濾器,這使得它非常方便用於消除、計數或識別重複元素

    >>> word = 'abracadabra'
    >>> letters = sorted(word)   # Turn string into a sorted list of letters
    >>> letters
    ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
    >>> for k, g in itertools.groupby(letters):
    ...    print k, list(g)
    ...
    a ['a', 'a', 'a', 'a', 'a']
    b ['b', 'b']
    c ['c']
    d ['d']
    r ['r', 'r']
    >>> # List unique letters
    >>> [k for k, g in groupby(letters)]
    ['a', 'b', 'c', 'd', 'r']
    >>> # Count letter occurrences
    >>> [(k, len(list(g))) for k, g in groupby(letters)]
    [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
    

    (由 Hye-Shik Chang 貢獻。)

  • itertools 還新增了一個名為 tee(iterator, N) 的函式,它返回 N 個獨立的迭代器,它們複製 iterator。如果省略 N,預設值為 2。

    >>> L = [1,2,3]
    >>> i1, i2 = itertools.tee(L)
    >>> i1,i2
    (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)
    >>> list(i1)               # Run the first iterator to exhaustion
    [1, 2, 3]
    >>> list(i2)               # Run the second iterator to exhaustion
    [1, 2, 3]
    

    請注意,tee() 必須保留迭代器返回的值的副本;在最壞的情況下,它可能需要保留所有副本。因此,如果領先迭代器在一個長輸入流中遠遠領先於跟隨迭代器,則應謹慎使用。如果分離很大,那麼您不妨使用 list()。當迭代器彼此密切跟蹤時,tee() 是理想的選擇。可能的應用包括書籤、視窗或前瞻迭代器。(由 Raymond Hettinger 貢獻。)

  • locale 模組添加了許多函式,例如 bind_textdomain_codeset() 用於指定特定編碼,以及一系列 l*gettext() 函式,它們以選定的編碼返回訊息。(由 Gustavo Niemeyer 貢獻。)

  • 一些關鍵字引數已新增到 logging 包的 basicConfig() 函式中,以簡化日誌配置。預設行為是將訊息記錄到標準錯誤,但可以指定各種關鍵字引數來記錄到特定檔案、更改日誌格式或設定日誌級別。例如

    import logging
    logging.basicConfig(filename='/var/log/application.log',
        level=0,  # Log all messages
        format='%(levelname):%(process):%(thread):%(message)')
    

    logging 包的其他新增功能包括一個方便的 log(level, msg) 方法,以及一個 TimedRotatingFileHandler 類,它以定時間隔輪換其日誌檔案。該模組已經有 RotatingFileHandler,它會在檔案超出特定大小時輪換日誌。這兩個類都派生自一個新的 BaseRotatingHandler 類,該類可用於實現其他輪換處理程式。

    (更改由 Vinay Sajip 實現。)

  • marshal 模組現在在解包資料結構時共享內部化字串。這可能會縮小某些 pickle 字串的大小,但主要效果是使 .pyc 檔案顯著減小。(由 Martin von Löwis 貢獻。)

  • nntplib 模組的 NNTP 類增加了 description()descriptions() 方法,用於檢索單個新聞組或一組新聞組的新聞組描述。(由 Jürgen A. Erhard 貢獻。)

  • operator 模組新增了兩個函式,attrgetter(attr)itemgetter(index)。這兩個函式都返回一個可呼叫物件,該物件接受一個引數並返回相應的屬性或項;當與 map()sorted() 一起使用時,這些可呼叫物件是出色的資料提取器。例如

    >>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
    >>> map(operator.itemgetter(0), L)
    ['c', 'd', 'a', 'b']
    >>> map(operator.itemgetter(1), L)
    [2, 1, 4, 3]
    >>> sorted(L, key=operator.itemgetter(1)) # Sort list by second tuple item
    [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
    

    (由 Raymond Hettinger 貢獻。)

  • optparse 模組以各種方式進行了更新。該模組現在將其訊息透過 gettext.gettext() 傳遞,從而可以實現 Optik 幫助和錯誤訊息的國際化。選項的幫助訊息現在可以包含字串 '%default',該字串將替換為選項的預設值。(由 Greg Ward 貢獻。)

  • 長期計劃是在未來的某個 Python 版本中棄用 rfc822 模組,轉而使用 email 包。為此,email.Utils.formatdate 函式已更改,使其可用作 rfc822.formatdate() 的替代品。您可能希望在編寫新的電子郵件處理程式碼時考慮這一點。(更改由 Anthony Baxter 實現。)

  • os 模組新增了 urandom(n) 函式,該函式返回一個包含 n 位元組隨機資料的字串。此函式提供對特定平臺隨機源的訪問,例如 Linux 上的 /dev/urandom 或 Windows CryptoAPI。(由 Trevor Perrin 貢獻。)

  • 另一個新函式:os.path.lexists(path) 如果 path 指定的檔案存在,則返回 true,無論它是否是符號連結。這與現有的 os.path.exists(path) 函式不同,後者如果 path 是一個指向不存在目的地的符號連結,則返回 false。(由 Beni Cherniavsky 貢獻。)

  • os 模組底層使用的 posix 模組新增了 getsid() 函式。(由 J. Raynor 貢獻。)

  • poplib 模組現在支援 POP over SSL。(由 Hector Urtubia 貢獻。)

  • profile 模組現在可以分析 C 擴充套件函式。(由 Nick Bastin 貢獻。)

  • random 模組有一個名為 getrandbits(N) 的新方法,該方法返回一個長度為 N 位的長整數。現有的 randrange() 方法現在在適當的情況下使用 getrandbits(),從而使任意大隨機數的生成更有效。(由 Raymond Hettinger 貢獻。)

  • re 模組接受的正則表示式語言透過簡單的條件表示式進行了擴充套件,寫為 (?(group)A|B)group 可以是數字組 ID 或在表示式前面用 (?P<group>...) 定義的組名。如果指定的組匹配,則正則表示式模式 A 將與字串進行測試;如果組不匹配,則將使用模式 B。(由 Gustavo Niemeyer 貢獻。)

  • re 模組也不再是遞迴的,這要歸功於 Gustavo Niemeyer 的大量工作。在遞迴正則表示式引擎中,某些模式會導致消耗大量的 C 堆疊空間,並且可能會導致堆疊溢位。例如,如果您將 30000 位元組的 a 字元字串與表示式 (a|b)+ 進行匹配,則每個字元都會消耗一個堆疊幀。Python 2.3 試圖檢查堆疊溢位並引發 RuntimeError 異常,但某些模式可能會繞過檢查,如果您運氣不好,Python 可能會出現段錯誤。Python 2.4 的正則表示式引擎可以毫無問題地匹配此模式。

  • signal 模組現在對 signal.signal() 函式的引數執行更嚴格的錯誤檢查。例如,您不能在 SIGKILL 訊號上設定處理程式;以前的 Python 版本會默默接受這一點,但 2.4 將引發 RuntimeError 異常。

  • socket 模組新增了兩個函式。socketpair() 返回一對已連線的套接字,getservbyport(port) 查詢給定埠號的服務名。(由 Dave Cole 和 Barry Warsaw 貢獻。)

  • sys.exitfunc() 函式已被棄用。程式碼應使用現有的 atexit 模組,該模組正確處理呼叫多個退出函式。最終 sys.exitfunc() 將成為一個純粹的內部介面,僅由 atexit 訪問。

  • tarfile 模組現在預設生成 GNU 格式的 tar 檔案。(由 Lars Gustäbel 貢獻。)

  • threading 模組現在提供了一種優雅簡單的方式來支援執行緒本地資料。該模組包含一個 local 類,其屬性值對不同的執行緒是本地的。

    import threading
    
    data = threading.local()
    data.number = 42
    data.url = ('www.python.org', 80)
    

    其他執行緒可以為 numberurl 屬性分配和檢索它們自己的值。您可以子類化 local 以初始化屬性或新增方法。(由 Jim Fulton 貢獻。)

  • timeit 模組現在在計時迴圈期間自動停用週期性垃圾回收。此更改使連續計時更具可比性。(由 Raymond Hettinger 貢獻。)

  • weakref 模組現在支援更廣泛的物件,包括 Python 函式、類例項、集合、不可變集合、雙端佇列、陣列、檔案、套接字和正則表示式模式物件。(由 Raymond Hettinger 貢獻。)

  • xmlrpclib 模組現在支援多呼叫擴充套件,用於在單個 HTTP 操作中傳輸多個 XML-RPC 呼叫。(由 Brian Quinlan 貢獻。)

  • mpzrotorxreadlines 模組已被刪除。

cookielib

cookielib 庫支援 HTTP cookie 的客戶端處理,與 Cookie 模組的伺服器端 cookie 支援相呼應。Cookie 儲存在 cookie jar 中;該庫透明地將 Web 伺服器提供的 cookie 儲存到 cookie jar 中,並在連線到伺服器時從 jar 中獲取 cookie。與 Web 瀏覽器一樣,策略物件控制是否接受 cookie。

為了在會話之間儲存 cookie,提供了兩種 cookie jar 的實現:一種以 Netscape 格式儲存 cookie,以便應用程式可以使用 Mozilla 或 Lynx cookie 檔案;另一種以 Perl libwww 庫相同的格式儲存 cookie。

urllib2 已更改為與 cookielib 互動:HTTPCookieProcessor 管理一個在訪問 URL 時使用的 cookie jar。

此模組由 John J. Lee 貢獻。

doctest

由於 Edward Loper 和 Tim Peters 的大量重構,doctest 模組進行了相當大的重構。測試仍然可以像執行 doctest.testmod() 一樣簡單,但重構允許以各種方式自定義模組的操作

新的 DocTestFinder 類從給定物件的文件字串中提取測試

def f (x, y):
    """>>> f(2,2)
4
>>> f(3,2)
6
    """
    return x*y

finder = doctest.DocTestFinder()

# Get list of DocTest instances
tests = finder.find(f)

新的 DocTestRunner 類然後執行單個測試並可以生成結果摘要

runner = doctest.DocTestRunner()
for t in tests:
    tried, failed = runner.run(t)

runner.summarize(verbose=1)

上面的例子產生以下輸出

1 items passed all tests:
   2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.

DocTestRunner 使用 OutputChecker 類的例項來比較預期輸出和實際輸出。此類別接受許多不同的標誌來定製其行為;有抱負的使用者還可以編寫一個全新的 OutputChecker 子類。

預設的輸出檢查器提供了許多方便的功能。例如,使用 doctest.ELLIPSIS 選項標誌,預期輸出中的省略號 (...) 匹配任何子字串,從而更容易適應在細微方面有所不同的輸出

def o (n):
    """>>> o(1)
<__main__.C instance at 0x...>
>>>
"""

另一個特殊字串,<BLANKLINE>,匹配一個空行

def p (n):
    """>>> p(1)
<BLANKLINE>
>>>
"""

另一個新功能是透過指定 doctest.REPORT_UDIFF(統一差異)、doctest.REPORT_CDIFF(上下文差異)或 doctest.REPORT_NDIFF(增量樣式)選項標誌來生成差異樣式輸出顯示。例如

def g (n):
    """>>> g(4)
here
is
a
lengthy
>>>"""
    L = 'here is a rather lengthy list of words'.split()
    for word in L[:n]:
        print word

使用指定的 doctest.REPORT_UDIFF 執行上述函式的測試,您將獲得以下輸出

**********************************************************************
File "t.py", line 15, in g
Failed example:
    g(4)
Differences (unified diff with -expected +actual):
    @@ -2,3 +2,3 @@
     is
     a
    -lengthy
    +rather
**********************************************************************

構建和 C API 更改

Python 構建過程和 C API 的一些更改是

  • 添加了三個新的方便宏,用於擴充套件函式的常見返回值:Py_RETURN_NONEPy_RETURN_TRUEPy_RETURN_FALSE。(由 Brett Cannon 貢獻。)

  • 另一個新宏 Py_CLEAR 減少了 obj 的引用計數並將 obj 設定為 null 指標。(由 Jim Fulton 貢獻。)

  • 一個新函式 PyTuple_Pack(N, obj1, obj2, ..., objN),從可變長度引數列表的 Python 物件構建元組。(由 Raymond Hettinger 貢獻。)

  • 一個新函式 PyDict_Contains(d, k),實現了快速字典查詢,而不會掩蓋查詢過程中引發的異常。(由 Raymond Hettinger 貢獻。)

  • 如果浮點或雙精度引數 X 是 NaN,Py_IS_NAN(X) 宏返回 1。(由 Tim Peters 貢獻。)

  • C 程式碼可以透過使用新的 PyEval_ThreadsInitialized() 函式來避免不必要的鎖定,該函式用於判斷是否執行了任何執行緒操作。如果此函式返回 false,則不需要鎖定操作。(由 Nick Coghlan 貢獻。)

  • 一個新函式 PyArg_VaParseTupleAndKeywords()PyArg_ParseTupleAndKeywords() 相同,但它接受 va_list 而不是多個引數。(由 Greg Chapman 貢獻。)

  • 一個新的方法標誌 METH_COEXIST 允許在槽中定義的函式與同名的 PyCFunction 共存。這可以將 set.__contains__() 等方法的訪問時間縮短一半。(由 Raymond Hettinger 貢獻。)

  • Python 現在可以為直譯器本身構建額外的效能分析,旨在幫助開發 Python 核心的人員。向 configure 指令碼提供 --enable-profiling 將允許您使用 gprof 對直譯器進行效能分析,提供 --with-tsc 開關將啟用使用奔騰的時間戳計數器暫存器進行效能分析。請注意,--with-tsc 開關名稱略有不當,因為效能分析功能也適用於 PowerPC 平臺,儘管該處理器架構不將該暫存器稱為“TSC 暫存器”。(由 Jeremy Hylton 貢獻。)

  • tracebackobject 型別已重新命名為 PyTracebackObject

特定於埠的更改

  • Windows 移植現在在 MSVC++ 7.1 和 6 版本下構建。(由 Martin von Löwis 貢獻。)

移植到 Python 2.4

本節列出了可能需要更改程式碼的先前描述的更改

  • 左移和過大的十六進位制/八進位制常量不再觸發 FutureWarning 並返回限制為 32 或 64 位的值;而是返回一個長整數。

  • 整數操作將不再觸發 OverflowWarningOverflowWarning 警告將在 Python 2.5 中消失。

  • 如果呼叫時沒有引數,內建函式 zip()itertools.izip() 現在返回一個空列表,而不是引發 TypeError 異常。

  • 您不能再比較 datetime 模組提供的 datedatetime 例項。現在,不同類的兩個例項將始終不相等,並且相對比較(<>)將引發 TypeError

  • dircache.listdir() 現在將異常傳遞給呼叫者,而不是返回空列表。

  • LexicalHandler.startDTD() 曾經以錯誤的順序接收公共和系統 ID。這已得到糾正;依賴於錯誤順序的應用程式需要修復。

  • 如果省略了 mutate 引數且相關,fcntl.ioctl() 現在會發出警告。

  • tarfile 模組現在預設生成 GNU 格式的 tar 檔案。

  • 在匯入模組時遇到失敗不再在 sys.modules 中留下部分初始化的模組物件。

  • None 現在是一個常量;將新值繫結到名稱 None 的程式碼現在是語法錯誤。

  • signals.signal() 函式現在對某些非法值引發 RuntimeError 異常;以前這些錯誤會默默地透過。例如,您不能再在 SIGKILL 訊號上設定處理程式。

致謝

作者要感謝以下人員為本文的各種草稿提供了建議、更正和幫助:Koray Can、Hye-Shik Chang、Michael Dyck、Raymond Hettinger、Brian Hurt、Hamish Lawson、Fredrik Lundh、Sean Reifschneider、Sadruddin Rejeb。