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
模組保留在標準庫中,如果您希望對 Set
或 ImmutableSet
類進行子類化,它可能會很有用。目前沒有計劃棄用該模組。
參見
- 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'
在編寫模板字串時,很容易忘記右括號後的 i
或 s
。如果模板在 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):
...
@classmethod
是 meth=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()
所做的那樣。)
stdin、stdout 和 stderr 指定子程序的輸入、輸出和錯誤流。您可以提供檔案物件或檔案描述符,也可以使用常量 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.01
是1 + 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 的標準庫中。它包含兩個類:Decimal
和 Context
。Decimal
例項表示數字,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
數字可以與 math
和 cmath
模組一起使用,但請注意,在執行操作之前,它們會立即轉換為浮點數,這可能會導致精度和準確性損失。您還將獲得一個普通的浮點數,而不是 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_DOWN
、ROUND_CEILING
、ROUND_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)
都將字串轉換為 Cdouble
。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()
方法增加了三個關鍵字引數:cmp、key 和 reverse。這些引數使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 貢獻。)
整數操作將不再觸發
OverflowWarning
。OverflowWarning
警告將在 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
現在,
Queue
和threading
等幾個模組利用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 狀態碼常量。常量名稱包括OK
、CREATED
、CONTINUE
和MOVED_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 貢獻。)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)
其他執行緒可以為
number
和url
屬性分配和檢索它們自己的值。您可以子類化local
以初始化屬性或新增方法。(由 Jim Fulton 貢獻。)timeit
模組現在在計時迴圈期間自動停用週期性垃圾回收。此更改使連續計時更具可比性。(由 Raymond Hettinger 貢獻。)weakref
模組現在支援更廣泛的物件,包括 Python 函式、類例項、集合、不可變集合、雙端佇列、陣列、檔案、套接字和正則表示式模式物件。(由 Raymond Hettinger 貢獻。)xmlrpclib
模組現在支援多呼叫擴充套件,用於在單個 HTTP 操作中傳輸多個 XML-RPC 呼叫。(由 Brian Quinlan 貢獻。)mpz
、rotor
和xreadlines
模組已被刪除。
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_NONE
、Py_RETURN_TRUE
和Py_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 位的值;而是返回一個長整數。整數操作將不再觸發
OverflowWarning
。OverflowWarning
警告將在 Python 2.5 中消失。如果呼叫時沒有引數,內建函式
zip()
和itertools.izip()
現在返回一個空列表,而不是引發TypeError
異常。您不能再比較
datetime
模組提供的date
和datetime
例項。現在,不同類的兩個例項將始終不相等,並且相對比較(<
,>
)將引發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。