Python 2.6 的新特性

作者:

A.M. Kuchling (amk at amk.ca)

本文解釋了 Python 2.6 的新功能,該版本於 2008 年 10 月 1 日釋出。釋出時間表在PEP 361中描述。

Python 2.6 的主要主題是為遷移到 Python 3.0 做準備,3.0 是對語言的重大重新設計。只要有可能,Python 2.6 會整合 3.0 的新功能和語法,同時透過不刪除舊功能或語法來保持與現有程式碼的相容性。當無法做到這一點時,Python 2.6 會盡力而為,在 future_builtins 模組中新增相容性函式,並新增 -3 開關來警告將在 3.0 中不受支援的用法。

標準庫中添加了一些重要的新包,例如 multiprocessingjson 模組,但與 Python 3.0 沒有以某種方式相關的新功能並不多。

Python 2.6 還在整個原始碼中進行了許多改進和錯誤修復。對更改日誌的搜尋發現,在 Python 2.5 和 2.6 之間應用了 259 個補丁,修復了 612 個錯誤。這兩個數字可能都被低估了。

本文不試圖提供新功能的完整規範,而是提供一個方便的概述。有關完整詳細資訊,您應參閱 Python 2.6 的文件。如果您想了解設計和實現的原理,請參閱特定新功能的 PEP。只要有可能,“Python 新特性”會連結到每個更改的錯誤/補丁專案。

Python 3.0

Python 2.6 和 3.0 版本的開發週期是同步的,兩個版本的 alpha 和 beta 版本在同一天釋出。3.0 的開發影響了 2.6 中的許多功能。

Python 3.0 是 Python 的一個廣泛重新設計,它打破了與 2.x 系列的相容性。這意味著現有的 Python 程式碼需要一些轉換才能在 Python 3.0 上執行。然而,3.0 中的所有更改不一定都會破壞相容性。在不會導致現有程式碼損壞的新功能的情況下,它們已回溯到 2.6 並在本文件中的適當位置進行描述。一些源自 3.0 的功能是

  • 用於將物件轉換為複數的 __complex__() 方法。

  • 捕獲異常的替代語法:except TypeError as exc

  • 新增 functools.reduce() 作為內建 reduce() 函式的同義詞。

Python 3.0 添加了幾個新的內建函式並更改了一些現有內建函式的語義。3.0 中新增的函式,如 bin(),已直接新增到 Python 2.6 中,但現有內建函式並未更改;相反,future_builtins 模組提供了具有 3.0 新語義的版本。為了與 3.0 相容而編寫的程式碼可以根據需要執行 from future_builtins import hex, map

一個新的命令列開關 -3,它啟用對將在 Python 3.0 中刪除的功能的警告。您可以使用此開關執行程式碼,以瞭解將程式碼移植到 3.0 需要多少工作。此開關的值可透過布林變數 sys.py3kwarning 在 Python 程式碼中獲取,並透過 Py_Py3kWarningFlag 在 C 擴充套件程式碼中獲取。

參見

3xxx 系列的 PEP,其中包含 Python 3.0 的提案。PEP 3000 描述了 Python 3.0 的開發過程。從PEP 3100 開始,它描述了 Python 3.0 的總體目標,然後探索提出特定功能的更高編號的 PEP。

開發流程的變更

在 2.6 開發期間,Python 開發流程經歷了兩次重大變更:我們從 SourceForge 的問題追蹤器切換到定製的 Roundup 安裝,並且文件從 LaTeX 轉換為 reStructuredText。

新問題追蹤器:Roundup

很長一段時間以來,Python 開發人員對 SourceForge 的 bug 跟蹤器越來越感到惱火。SourceForge 的託管解決方案不允許進行太多自定義;例如,無法自定義問題的生命週期。

因此,Python 軟體基金會的基礎設施委員會發布了徵集問題跟蹤器的請求,要求志願者設定不同的產品並從 SourceForge 匯入一些錯誤和補丁。檢查了四種不同的跟蹤器:JiraLaunchpadRoundupTrac。委員會最終選擇了 Jira 和 Roundup 作為兩個候選者。Jira 是一種商業產品,為免費軟體專案提供免費託管例項;Roundup 是一個開源專案,需要志願者來管理它並需要伺服器來託管它。

在釋出志願者招募後,一個新的 Roundup 安裝在 https://bugs.python.org 建立。一個 Roundup 安裝可以託管多個追蹤器,現在這個伺服器也託管 Jython 和 Python 網站的問題追蹤器。它將來肯定會找到其他用途。在可能的情況下,此版本的“Python 新功能”會連結到每個更改的 bug/補丁項。

Python bug 跟蹤器的託管由南非斯泰倫博斯(Stellenbosch)的 Upfront Systems 友情提供。Martin von Löwis 在從 SourceForge 匯入現有 bug 和補丁方面付出了大量努力;他的匯入操作指令碼位於 https://svn.python.org/view/tracker/importer/,對於希望從 SourceForge 遷移到 Roundup 的其他專案可能很有用。

參見

https://bugs.python.org

Python 錯誤追蹤器。

https://bugs.jython.org:

Jython 錯誤追蹤器。

https://roundup.sourceforge.io/

Roundup 下載和文件。

https://svn.python.org/view/tracker/importer/

Martin von Löwis 的轉換指令碼。

新的文件格式:使用 Sphinx 的 reStructuredText

自專案於 1989 年左右啟動以來,Python 文件一直使用 LaTeX 編寫。在 1980 年代和 1990 年代初期,大多數文件都是打印出來供以後學習,而不是線上檢視。LaTeX 被廣泛使用,因為它提供了美觀的列印輸出,同時在學習了標記的基本規則後仍然易於編寫。

如今,LaTeX 仍然用於編寫用於列印的出版物,但程式設計工具的環境已經發生了變化。我們不再列印大量的文件;相反,我們線上瀏覽它們,HTML 已成為最重要的支援格式。不幸的是,將 LaTeX 轉換為 HTML 相當複雜,長期擔任 Python 文件編輯的 Fred L. Drake Jr. 花費了大量時間維護轉換過程。偶爾有人會建議將文件轉換為 SGML,後來又轉換為 XML,但進行良好的轉換是一項重大任務,沒有人願意投入所需的時間來完成這項工作。

在 2.6 開發週期中,Georg Brandl 投入了大量精力構建了一個新的工具鏈來處理文件。由此產生的軟體包名為 Sphinx,可從 https://www.sphinx-doc.org/ 獲取。

Sphinx 專注於 HTML 輸出,生成美觀時尚的 HTML;透過轉換為 LaTeX 仍然支援列印輸出。輸入格式是 reStructuredText,一種支援自定義擴充套件和指令的標記語法,在 Python 社群中常用。

Sphinx 是一個可用於編寫的獨立軟體包,還有將近二十個其他專案(在 Sphinx 網站上列出)已採用 Sphinx 作為其文件工具。

參見

記錄 Python

描述如何為 Python 的文件編寫。

Sphinx

Sphinx 工具鏈的文件和程式碼。

Docutils

底層的 reStructuredText 解析器和工具集。

PEP 343: ‘with’ 語句

上一個版本 Python 2.5 添加了“with”語句作為可選功能,透過 from __future__ import with_statement 指令啟用。在 2.6 中,該語句不再需要特殊啟用;這意味著 with 現在始終是關鍵字。本節的其餘部分是“Python 2.5 新功能”文件中相應部分的副本;如果您熟悉 Python 2.5 中的“with”語句,則可以跳過本節。

with”語句澄清了以前會使用 try...finally 塊來確保清理程式碼執行的程式碼。在本節中,我將討論該語句的常見用法。在下一節中,我將研究實現細節並展示如何編寫用於該語句的物件。

with”語句是一種控制流結構,其基本結構是

with expression [as variable]:
    with-block

表示式被求值,它應該返回一個支援上下文管理協議的物件(即,具有 __enter__()__exit__() 方法)。

在執行 with-block 之前,會呼叫物件的 __enter__(),因此可以執行設定程式碼。它還可能返回一個值,如果給出,則繫結到名稱 variable。(請注意,variable 被賦值為 expression 的結果。)

with-block 執行完畢後,即使該塊丟擲異常,也會呼叫物件的 __exit__() 方法,因此可以執行清理程式碼。

一些標準的 Python 物件現在支援上下文管理協議,並且可以與“with”語句一起使用。檔案物件就是其中一個例子

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line
        ... more processing code ...

該語句執行後,f 中的檔案物件將自動關閉,即使 for 迴圈在塊執行中途丟擲異常。

備註

在這種情況下,f 是由 open() 建立的同一物件,因為 __enter__() 返回 self

threading 模組的鎖和條件變數也支援“with”語句

lock = threading.Lock()
with lock:
    # Critical section of code
    ...

鎖在塊執行前被獲取,並在塊完成後始終釋放。

decimal 模組中的 localcontext() 函式使得儲存和恢復當前十進位制上下文變得容易,它封裝了計算所需的精度和舍入特性

from decimal import Decimal, Context, localcontext

# Displays with default precision of 28 digits
v = Decimal('578')
print v.sqrt()

with localcontext(Context(prec=16)):
    # All code in this block uses a precision of 16 digits.
    # The original context is restored on exiting the block.
    print v.sqrt()

編寫上下文管理器

在底層,“with”語句相當複雜。大多數人只會將“with”與現有物件一起使用,不需要了解這些細節,所以如果你願意,可以跳過本節的其餘部分。新物件的作者需要了解底層實現的細節,並應繼續閱讀。

上下文管理協議的高層解釋是

  • 表示式被求值,並且應該返回一個稱為“上下文管理器”的物件。上下文管理器必須具有 __enter__()__exit__() 方法。

  • 呼叫上下文管理器的 __enter__() 方法。返回的值將賦值給 VAR。如果不存在 as VAR 子句,則該值將被簡單地丟棄。

  • 執行 BLOCK 中的程式碼。

  • 如果 BLOCK 丟擲異常,則會呼叫上下文管理器的 __exit__() 方法,並帶上三個引數,即異常詳細資訊(type, value, traceback,與 sys.exc_info() 返回的值相同,如果沒有發生異常,也可以是 None)。該方法的返回值控制異常是否重新丟擲:任何假值都會重新丟擲異常,而 True 將導致抑制異常。您很少會希望抑制異常,因為如果您這樣做,包含“with”語句的程式碼的作者將永遠不會意識到出了問題。

  • 如果 BLOCK 沒有丟擲異常,__exit__() 方法仍然會被呼叫,但 typevaluetraceback 都為 None

讓我們來看一個例子。我不會提供詳細的程式碼,只會粗略地介紹支援事務的資料庫所需的方法。

(對於不熟悉資料庫術語的人:對資料庫的一組更改被分組到事務中。事務可以被提交,這意味著所有更改都寫入資料庫,或者被回滾,這意味著所有更改都被丟棄,資料庫保持不變。有關更多資訊,請參閱任何資料庫教科書。)

假設有一個代表資料庫連線的物件。我們的目標是讓使用者編寫如下程式碼

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... more operations ...

如果塊中的程式碼執行完美,事務應該被提交;如果出現異常,事務應該被回滾。這是我將假定的 DatabaseConnection 的基本介面

class DatabaseConnection:
    # Database interface
    def cursor(self):
        "Returns a cursor object and starts a new transaction"
    def commit(self):
        "Commits current transaction"
    def rollback(self):
        "Rolls back current transaction"

__enter__() 方法非常簡單,只需開始一個新事務。對於此應用程式,生成的遊標物件將是一個有用的結果,因此該方法將返回它。使用者隨後可以向其“with”語句新增 as cursor,將遊標繫結到變數名。

class DatabaseConnection:
    ...
    def __enter__(self):
        # Code to start a new transaction
        cursor = self.cursor()
        return cursor

__exit__() 方法是最複雜的,因為大部分工作必須在這裡完成。該方法必須檢查是否發生了異常。如果沒有異常,事務將被提交。如果發生異常,事務將被回滾。

在下面的程式碼中,執行將直接跳出函式末尾,返回預設值 NoneNone 為假,因此異常將自動重新丟擲。如果您願意,可以更明確地在標記位置新增一個 return 語句。

class DatabaseConnection:
    ...
    def __exit__(self, type, value, tb):
        if tb is None:
            # No exception, so commit
            self.commit()
        else:
            # Exception occurred, so rollback.
            self.rollback()
            # return False

contextlib 模組

contextlib 模組提供了一些函式和一個裝飾器,這些函式和裝飾器在編寫用於“with”語句的物件時很有用。

裝飾器名為 contextmanager(),它允許您編寫一個生成器函式,而不是定義一個新類。該生成器應該精確地產生一個值。直到 yield 的程式碼將作為 __enter__() 方法執行,產生的值將是該方法的返回值,如果“with”語句的 as 子句存在,則會繫結到變數。 yield 之後的程式碼將在 __exit__() 方法中執行。塊中引發的任何異常都將由 yield 語句引發。

使用這個裝飾器,我們上一節中的資料庫示例可以寫成

from contextlib import contextmanager

@contextmanager
def db_transaction(connection):
    cursor = connection.cursor()
    try:
        yield cursor
    except:
        connection.rollback()
        raise
    else:
        connection.commit()

db = DatabaseConnection()
with db_transaction(db) as cursor:
    ...

contextlib 模組還有一個 nested(mgr1, mgr2, ...) 函式,它可以組合多個上下文管理器,這樣您就不需要編寫巢狀的“with”語句。在這個例子中,單個“with”語句既啟動了資料庫事務又獲取了執行緒鎖

lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
    ...

最後,closing() 函式返回其引數,以便它可以繫結到變數,並在塊結束時呼叫引數的 .close() 方法。

import urllib, sys
from contextlib import closing

with closing(urllib.urlopen('http://www.yahoo.com')) as f:
    for line in f:
        sys.stdout.write(line)

參見

PEP 343 - "with" 語句

PEP 由 Guido van Rossum 和 Nick Coghlan 編寫;由 Mike Bland, Guido van Rossum 和 Neal Norwitz 實現。PEP 展示了為“with”語句生成的程式碼,這有助於瞭解該語句的工作原理。

contextlib 模組的文件。

PEP 366: 主模組中顯式相對匯入

Python 的 -m 開關允許將模組作為指令碼執行。當您執行位於包內的模組時,相對匯入無法正常工作。

Python 2.6 的修復添加了 module.__package__ 屬性。當此屬性存在時,相對匯入將相對於此屬性的值而不是 __name__ 屬性。

PEP 302 風格的匯入器可以根據需要設定 __package__。實現 -m 開關的 runpy 模組現在會這樣做,因此相對匯入現在將在包內部執行的指令碼中正常工作。

PEP 370: 每個使用者的 site-packages 目錄

當您執行 Python 時,模組搜尋路徑 sys.path 通常包含一個路徑以 "site-packages" 結尾的目錄。此目錄旨在存放本地安裝的包,供使用一臺機器或特定站點安裝的所有使用者使用。

Python 2.6 引入了使用者特定站點目錄的約定。該目錄因平臺而異

  • Unix 和 Mac OS X:~/.local/

  • Windows:%APPDATA%/Python

在此目錄中,將有特定於版本的子目錄,例如 Unix/Mac OS 上的 lib/python2.6/site-packages 和 Windows 上的 Python26/site-packages

如果您不喜歡預設目錄,可以透過環境變數覆蓋它。PYTHONUSERBASE 設定了支援此功能的所有 Python 版本使用的根目錄。在 Windows 上,可以透過設定 APPDATA 環境變數來更改特定於應用程式資料的目錄。您還可以修改 Python 安裝的 site.py 檔案。

可以透過使用 -s 選項執行 Python 或設定 PYTHONNOUSERSITE 環境變數來完全停用此功能。

參見

PEP 370 - 每個使用者的 site-packages 目錄

PEP 由 Christian Heimes 編寫並實現。

PEP 371: multiprocessing

新的 multiprocessing 包允許 Python 程式建立新的程序,這些程序將執行計算並向父程序返回結果。父子程序可以使用佇列和管道進行通訊,使用鎖和訊號量同步操作,並且可以共享簡單的資料陣列。

multiprocessing 模組最初是 threading 模組的精確模擬,使用程序而不是執行緒。這個目標在 Python 2.6 的開發過程中被放棄了,但是該模組的總體方法仍然相似。基本類是 Process,它傳遞一個可呼叫物件和一組引數。start() 方法在子程序中啟動可呼叫物件,之後您可以呼叫 is_alive() 方法檢查子程序是否仍在執行,以及 join() 方法等待程序退出。

這是一個簡單的例子,子程序將計算一個階乘。計算函式編寫得很奇怪,因此當輸入引數是 4 的倍數時,它需要明顯更長的時間。

import time
from multiprocessing import Process, Queue


def factorial(queue, N):
    "Compute a factorial."
    # If N is a multiple of 4, this function will take much longer.
    if (N % 4) == 0:
        time.sleep(.05 * N/4)

    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Put the result on the queue
    queue.put(fact)

if __name__ == '__main__':
    queue = Queue()

    N = 5

    p = Process(target=factorial, args=(queue, N))
    p.start()
    p.join()

    result = queue.get()
    print 'Factorial', N, '=', result

一個 Queue 用於傳遞階乘的結果。Queue 物件儲存在一個全域性變數中。子程序將使用子程序建立時變數的值;因為它是一個 Queue,父程序和子程序可以使用該物件進行通訊。(如果父程序更改全域性變數的值,子程序的值將不受影響,反之亦然。)

另外兩個類,PoolManager,提供更高級別的介面。Pool 將建立固定數量的工作程序,然後可以透過呼叫 apply()apply_async() 來新增單個請求,以及呼叫 map()map_async() 來新增多個請求,從而將請求分發給工作程序。以下程式碼使用 Pool 將請求分散到 5 個工作程序中並檢索結果列表

from multiprocessing import Pool

def factorial(N, dictionary):
    "Compute a factorial."
    ...
p = Pool(5)
result = p.map(factorial, range(1, 1000, 10))
for v in result:
    print v

這會產生以下輸出:

1
39916800
51090942171709440000
8222838654177922817725562880000000
33452526613163807108170062053440751665152000000000
...

另一個高階介面,Manager 類,建立一個單獨的伺服器程序,該程序可以持有 Python 資料結構的主副本。其他程序隨後可以使用代理物件訪問和修改這些資料結構。以下示例透過呼叫 dict() 方法建立一個共享字典;然後工作程序將值插入字典。(鎖定不是自動完成的,這在本例中無關緊要。Manager 的方法還包括 Lock()RLock()Semaphore() 來建立共享鎖。)

import time
from multiprocessing import Pool, Manager

def factorial(N, dictionary):
    "Compute a factorial."
    # Calculate the result
    fact = 1L
    for i in range(1, N+1):
        fact = fact * i

    # Store result in dictionary
    dictionary[N] = fact

if __name__ == '__main__':
    p = Pool(5)
    mgr = Manager()
    d = mgr.dict()         # Create shared dictionary

    # Run tasks using the pool
    for N in range(1, 1000, 10):
        p.apply_async(factorial, (N, d))

    # Mark pool as closed -- no more tasks can be added.
    p.close()

    # Wait for tasks to exit
    p.join()

    # Output results
    for k, v in sorted(d.items()):
        print k, v

這將產生以下輸出

1 1
11 39916800
21 51090942171709440000
31 8222838654177922817725562880000000
41 33452526613163807108170062053440751665152000000000
51 15511187532873822802242430164693032110632597200169861120000...

參見

multiprocessing 模組的文件。

PEP 371 - 新增多程序包

PEP 由 Jesse Noller 和 Richard Oudkerk 編寫;由 Richard Oudkerk 和 Jesse Noller 實現。

PEP 3101: 高階字串格式化

在 Python 3.0 中,% 運算子由更強大的字串格式化方法 format() 補充。對 str.format() 方法的支援已回溯到 Python 2.6。

在 2.6 中,8 位字串和 Unicode 字串都有一個 .format() 方法,它將字串視為模板並獲取要格式化的引數。格式化模板使用花括號 ({, }) 作為特殊字元

>>> # Substitute positional argument 0 into the string.
>>> "User ID: {0}".format("root")
'User ID: root'
>>> # Use the named keyword arguments
>>> "User ID: {uid}   Last seen: {last_login}".format(
...    uid="root",
...    last_login = "5 Mar 2008 07:20")
'User ID: root   Last seen: 5 Mar 2008 07:20'

花括號可以透過加倍來轉義

>>> "Empty dict: {{}}".format()
"Empty dict: {}"

欄位名稱可以是表示位置引數的整數,例如 {0}{1} 等,也可以是關鍵字引數的名稱。您還可以提供複合字段名稱來讀取屬性或訪問字典鍵

>>> import sys
>>> print 'Platform: {0.platform}\nPython version: {0.version}'.format(sys)
Platform: darwin
Python version: 2.6a1+ (trunk:61261M, Mar  5 2008, 20:29:41)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)]'

>>> import mimetypes
>>> 'Content-type: {0[.mp4]}'.format(mimetypes.types_map)
'Content-type: video/mp4'

請注意,在使用字典風格的表示法(例如 [.mp4])時,您不需要在字串周圍加上任何引號;它會使用 .mp4 作為鍵來查詢值。以數字開頭的字串將轉換為整數。您不能在格式字串中編寫更復雜的表示式。

到目前為止,我們已經展示瞭如何指定要替換到結果字串中的欄位。所使用的精確格式也可以透過新增一個冒號和格式說明符來控制。例如

>>> # Field 0: left justify, pad to 15 characters
>>> # Field 1: right justify, pad to 6 characters
>>> fmt = '{0:15} ${1:>6}'
>>> fmt.format('Registration', 35)
'Registration    $    35'
>>> fmt.format('Tutorial', 50)
'Tutorial        $    50'
>>> fmt.format('Banquet', 125)
'Banquet         $   125'

格式說明符可以透過巢狀引用其他欄位

>>> fmt = '{0:{1}}'
>>> width = 15
>>> fmt.format('Invoice #1234', width)
'Invoice #1234  '
>>> width = 35
>>> fmt.format('Invoice #1234', width)
'Invoice #1234                      '

可以指定欄位在所需寬度內的對齊方式

字元

效果

< (預設)

左對齊

>

右對齊

^

居中

=

(僅適用於數字型別)在符號後填充。

格式說明符還可以包含表示型別,它控制值的格式。例如,浮點數可以格式化為通用數字或指數表示法

>>> '{0:g}'.format(3.75)
'3.75'
>>> '{0:e}'.format(3.75)
'3.750000e+00'

有多種呈現型別可用。有關完整列表,請查閱 2.6 文件;這裡是一些示例

b

二進位制。以 2 為基數輸出數字。

c

字元。在列印前將整數轉換為相應的 Unicode 字元。

d

十進位制整數。以 10 為基數輸出數字。

o

八進位制格式。以 8 為基數輸出數字。

x

十六進位制格式。以 16 為基數輸出數字,9 以上的數字使用小寫字母。

e

指數表示法。以科學記數法列印數字,使用字母“e”表示指數。

g

通用格式。這會將數字列印為定點數,除非數字太大,在這種情況下它會切換到“e”指數表示法。

n

數字。這與“g”(對於浮點數)或“d”(對於整數)相同,只是它使用當前區域設定來插入適當的數字分隔符。

%

百分比。將數字乘以 100 並以定點('f')格式顯示,後跟一個百分號。

類和型別可以定義 __format__() 方法來控制它們的格式。它接收一個引數,即格式說明符

def __format__(self, format_spec):
    if isinstance(format_spec, unicode):
        return unicode(str(self))
    else:
        return str(self)

還有一個 format() 內建函式,它將格式化單個值。它使用提供的說明符呼叫型別的 __format__() 方法

>>> format(75.6564, '.2f')
'75.66'

參見

格式字串語法

格式欄位的參考文件。

PEP 3101 - 高階字串格式化

PEP 由 Talin 編寫。由 Eric Smith 實現。

PEP 3105: print 作為函式

在 Python 3.0 中,print 語句變為 print() 函式。將 print() 設為函式使得透過執行 def print(...) 或從其他地方匯入新函式來替換該函式成為可能。

Python 2.6 有一個 __future__ 匯入,它將 print 從語言語法中移除,讓您可以使用函式形式。例如

>>> from __future__ import print_function
>>> print('# of entries', len(dictionary), file=sys.stderr)

新函式的簽名是

def print(*args, sep=' ', end='\n', file=None)

引數為

  • args: 要列印的定位引數的值。

  • sep: 分隔符,將列印在引數之間。

  • end: 結束文字,將在所有引數輸出後列印。

  • file: 輸出將傳送到的檔案物件。

參見

PEP 3105 - 將 print 設為函式

PEP 由 Georg Brandl 編寫。

PEP 3110: 異常處理變更

Python 程式設計師偶爾會犯的一個錯誤是編寫以下程式碼

try:
    ...
except TypeError, ValueError:  # Wrong!
    ...

作者可能試圖捕獲 TypeErrorValueError 異常,但這段程式碼實際上做了不同的事情:它會捕獲 TypeError 並將產生的異常物件繫結到區域性名稱 "ValueError"ValueError 異常根本不會被捕獲。正確的程式碼指定了一個異常元組

try:
    ...
except (TypeError, ValueError):
    ...

這個錯誤發生是因為這裡的逗號用法是模稜兩可的:它表示解析樹中的兩個不同的節點,還是一個單一的元組節點?

Python 3.0 透過將逗號替換為“as”來使其明確。要捕獲異常並將其異常物件儲存在變數 exc 中,您必須編寫

try:
    ...
except TypeError as exc:
    ...

Python 3.0 只支援使用“as”,因此將第一個示例解釋為捕獲兩個不同的異常。Python 2.6 同時支援逗號和“as”,因此現有程式碼將繼續工作。因此,我們建議在編寫僅在 2.6 中執行的新 Python 程式碼時使用“as”。

參見

PEP 3110 - 在 Python 3000 中捕獲異常

PEP 由 Collin Winter 編寫並實現。

PEP 3112: 位元組字面量

Python 3.0 採用 Unicode 作為語言的基本字串型別,並以不同的方式表示 8 位字面量,可以是 b'string' 或使用 bytes 建構函式。為了未來的相容性,Python 2.6 添加了 bytes 作為 str 型別的同義詞,並且它也支援 b'' 符號。

2.6 的 str 與 3.0 的 bytes 型別在多種方面有所不同;最顯著的是,建構函式完全不同。在 3.0 中,bytes([65, 66, 67]) 的長度為 3,包含表示 ABC 的位元組;在 2.6 中,bytes([65, 66, 67]) 返回表示列表 str() 的 12 位元組字串。

2.6 中 bytes 的主要用途將是編寫物件型別測試,例如 isinstance(x, bytes)。這將有助於 2to3 轉換器,它無法判斷 2.x 程式碼是打算讓字串包含字元還是 8 位位元組;您現在可以使用 bytesstr 來精確表示您的意圖,並且生成的程式碼在 Python 3.0 中也將是正確的。

還有一個 __future__ 匯入,它導致所有字串字面量都成為 Unicode 字串。這意味著可以使用 \u 轉義序列來包含 Unicode 字元

from __future__ import unicode_literals

s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
     '\u3081\u3000\u751f\u305f\u307e\u3054')

print len(s)               # 12 Unicode characters

在 C 層面,Python 3.0 將把現有的 8 位字串型別(在 Python 2.x 中稱為 PyStringObject)重新命名為 PyBytesObject。Python 2.6 使用 #define 來支援使用名稱 PyBytesObject()PyBytes_Check()PyBytes_FromStringAndSize() 以及所有其他用於字串的函式和宏。

bytes 型別的例項與字串一樣是不可變的。新的 bytearray 型別儲存可變的位元組序列

>>> bytearray([65, 66, 67])
bytearray(b'ABC')
>>> b = bytearray(u'\u21ef\u3244', 'utf-8')
>>> b
bytearray(b'\xe2\x87\xaf\xe3\x89\x84')
>>> b[0] = '\xe3'
>>> b
bytearray(b'\xe3\x87\xaf\xe3\x89\x84')
>>> unicode(str(b), 'utf-8')
u'\u31ef \u3244'

位元組陣列支援字串型別的大多數方法,例如 startswith()/endswith()find()/rfind(),以及列表的一些方法,例如 append()pop()reverse()

>>> b = bytearray('ABC')
>>> b.append('d')
>>> b.append(ord('e'))
>>> b
bytearray(b'ABCde')

還有相應的 C API,包括 PyByteArray_FromObject()PyByteArray_FromStringAndSize() 以及各種其他函式。

參見

PEP 3112 - Python 3000 中的位元組字面量

PEP 由 Jason Orendorff 編寫;由 Christian Heimes 回溯到 2.6。

PEP 3116: 新的 I/O 庫

Python 的內建檔案物件支援多種方法,但類檔案物件不一定支援所有方法。模擬檔案的物件通常支援 read()write(),但它們可能不支援 readline(),例如。Python 3.0 在 io 模組中引入了一個分層 I/O 庫,它將緩衝和文字處理功能從基本的讀寫操作中分離出來。

io 模組提供了三個級別的抽象基類

  • RawIOBase 定義了原始 I/O 操作:read()readinto()write()seek()tell()truncate()close()。此類的大多數方法通常會對映到單個系統呼叫。還有 readable()writable()seekable() 方法,用於確定給定物件允許的操作。

    Python 3.0 對檔案和套接字提供了此類的具體實現,但 Python 2.6 尚未以這種方式重構其檔案和套接字物件。

  • BufferedIOBase 是一個抽象基類,它在記憶體中緩衝資料以減少系統呼叫次數,從而提高 I/O 處理效率。它支援 RawIOBase 的所有方法,並添加了一個 raw 屬性,用於儲存底層的原始物件。

    有五個實現此抽象基類的具體類。BufferedWriterBufferedReader 用於支援只寫或只讀用法且具有用於隨機訪問的 seek() 方法的物件。BufferedRandom 物件支援在同一底層流上進行讀寫訪問,而 BufferedRWPair 用於諸如 TTY 等物件,它們在不相關的資料流上執行讀寫操作。BytesIO 類支援在記憶體緩衝區上進行讀、寫和查詢。

  • TextIOBase:提供用於讀寫字串的函式(記住,在 Python 3.0 中,字串將是 Unicode),並支援通用換行符TextIOBase 定義了 readline() 方法並支援對物件進行迭代。

    有兩個具體的實現。TextIOWrapper 包裝了一個緩衝 I/O 物件,支援文字 I/O 的所有方法,並添加了一個 buffer 屬性來訪問底層物件。StringIO 只是將所有內容緩衝在記憶體中,而不會寫入磁碟。

    (在 Python 2.6 中,io.StringIO 是純 Python 實現的,所以它很慢。因此,您現在應該堅持使用現有的 StringIO 模組或 cStringIO。Python 3.0 的 io 模組遲早會用 C 語言重寫以提高速度,也許 C 實現會回溯到 2.x 版本。)

在 Python 2.6 中,底層實現尚未重構以構建在 io 模組的類之上。提供該模組是為了更容易編寫與 3.0 向前相容的程式碼,並節省開發人員編寫自己的緩衝和文字 I/O 實現的精力。

參見

PEP 3116 - 新 I/O

PEP 由 Daniel Stutzbach、Mike Verdone 和 Guido van Rossum 編寫。程式碼由 Guido van Rossum、Georg Brandl、Walter Doerwald、Jeremy Hylton、Martin von Löwis、Tony Lownds 等人編寫。

PEP 3118: 修訂的緩衝區協議

緩衝區協議是一個 C 級 API,它允許 Python 型別交換指向其內部表示的指標。例如,記憶體對映檔案可以被視為一個字元緩衝區,這使得另一個模組(如 re)可以將記憶體對映檔案視為要搜尋的字元字串。

緩衝區協議的主要使用者是 NumPy 等數值處理包,它們暴露陣列的內部表示,以便呼叫者可以直接將資料寫入陣列,而不是透過較慢的 API。此 PEP 根據 NumPy 開發的經驗更新了緩衝區協議,添加了一些新功能,例如指示陣列的形狀或鎖定記憶體區域。

最重要的新的 C API 函式是 PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags),它接受一個物件和一組標誌,並用有關物件的記憶體表示的資訊填充 Py_buffer 結構體。物件可以使用此操作將記憶體鎖定在適當位置,而外部呼叫者可以修改內容,因此有一個相應的 PyBuffer_Release(Py_buffer *view) 來指示外部呼叫者已完成操作。

PyObject_GetBuffer()flags 引數指定了對返回記憶體的約束。一些示例如下

  • PyBUF_WRITABLE 表示記憶體必須可寫。

  • PyBUF_LOCK 請求對記憶體進行只讀或排他鎖。

  • PyBUF_C_CONTIGUOUSPyBUF_F_CONTIGUOUS 請求 C 連續(最後一維變化最快)或 Fortran 連續(第一維變化最快)的陣列佈局。

PyArg_ParseTuple() 的兩個新引數程式碼 s*z*,返回引數的鎖定緩衝區物件。

參見

PEP 3118 - 修訂緩衝區協議

PEP 由 Travis Oliphant 和 Carl Banks 編寫;由 Travis Oliphant 實現。

PEP 3119: 抽象基類

一些面嚮物件語言,如 Java,支援介面,宣告一個類具有一組給定的方法或支援給定的訪問協議。抽象基類(或 ABC)是 Python 的等效功能。AB​​C 支援包括一個 abc 模組,其中包含一個名為 ABCMeta 的元類,內建的 isinstance()issubclass() 對此元類進行特殊處理,以及 Python 開發人員認為將廣泛有用的一系列基本 ABC。未來的 Python 版本可能會新增更多的 ABC。

假設您有一個特定的類,並且希望知道它是否支援字典風格的訪問。“字典風格”這個詞是模糊的。它可能意味著用 obj[1] 訪問專案有效。它是否意味著用 obj[2] = value 設定專案有效?或者物件將有 keys()values()items() 方法?迭代變體,如 iterkeys() 呢?copy`和 :meth:()!update`?用 iter() 迭代物件呢?

Python 2.6 的 collections 模組包含許多不同的 ABC,它們代表這些區別。Iterable 表示一個類定義了 __iter__(),而 Container 意味著該類定義了 __contains__() 方法,因此支援 x in y 表示式。獲取專案、設定專案以及 keys()values()items() 的基本字典介面由 MutableMapping ABC 定義。

您可以從特定的 ABC 派生自己的類,以表明它們支援該 ABC 的介面

import collections

class Storage(collections.MutableMapping):
    ...

或者,您可以不從所需的 ABC 派生類,而是透過呼叫 ABC 的 register() 方法來註冊類

import collections

class Storage:
    ...

collections.MutableMapping.register(Storage)

對於您編寫的類,從 ABC 派生可能更清晰。當您編寫了一個新的 ABC,可以描述現有型別或類,或者您想宣告某個第三方類實現了某個 ABC 時,register() 方法很有用。例如,如果您定義了一個 PrintableType ABC,那麼執行以下操作是合法的

# Register Python's types
PrintableType.register(int)
PrintableType.register(float)
PrintableType.register(str)

類應遵守 ABC 指定的語義,但 Python 無法檢查這一點;這取決於類作者理解 ABC 的要求並相應地實現程式碼。

要檢查物件是否支援特定介面,您現在可以編寫

def func(d):
    if not isinstance(d, collections.MutableMapping):
        raise ValueError("Mapping object expected, not %r" % d)

不要覺得現在必須像上面的例子那樣開始編寫大量的檢查。Python 有一個強大的鴨子型別傳統,其中從不進行顯式型別檢查,程式碼只是呼叫物件上的方法,相信這些方法會存在,如果不存在則會引發異常。在檢查 ABC 時要審慎,只在絕對必要時才進行檢查。

您可以透過在類定義中使用 abc.ABCMeta 作為元類來編寫自己的 ABC

from abc import ABCMeta, abstractmethod

class Drawable():
    __metaclass__ = ABCMeta

    @abstractmethod
    def draw(self, x, y, scale=1.0):
        pass

    def draw_doubled(self, x, y):
        self.draw(x, y, scale=2.0)


class Square(Drawable):
    def draw(self, x, y, scale):
        ...

在上述 Drawable ABC 中,draw_doubled() 方法將物件渲染為原始大小的兩倍,並且可以透過 Drawable 中描述的其他方法實現。因此,實現此 ABC 的類不需要提供自己的 draw_doubled() 實現,儘管它們可以這樣做。但是,draw() 的實現是必需的;ABC 無法提供有用的通用實現。

您可以將 @~abc.abstractmethod 裝飾器應用於必須實現的方法,例如 draw();如果類沒有定義該方法,Python 將引發異常。請注意,只有當您實際嘗試建立缺少該方法的子類例項時,才會引發異常。

>>> class Circle(Drawable):
...     pass
...
>>> c = Circle()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Circle with abstract methods draw
>>>

抽象資料屬性可以使用 @abstractproperty 裝飾器宣告。

from abc import abstractproperty
...

@abstractproperty
def readonly(self):
   return self._x

子類必須定義一個 readonly 屬性。

參見

PEP 3119 - 引入抽象基類

PEP 由 Guido van Rossum 和 Talin 撰寫。由 Guido van Rossum 實現。由 Benjamin Aranguren 和 Alex Martelli 反向移植到 2.6。

PEP 3127: 整數字面量支援和語法

Python 3.0 改變了八進位制(base-8)整數字面量的語法,用“0o”或“0O”而不是前導零作為字首,並增加了對二進位制(base-2)整數字面量的支援,以“0b”或“0B”字首表示。

Python 2.6 並沒有放棄對前導 0 表示八進位制數字的支援,但它確實增加了對“0o”和“0b”的支援。

>>> 0o21, 2*8 + 1
(17, 17)
>>> 0b101111
47

oct() 內建函式仍然返回帶前導零的數字,並且一個新的 bin() 內建函式返回數字的二進位制表示。

>>> oct(42)
'052'
>>> future_builtins.oct(42)
'0o52'
>>> bin(173)
'0b10101101'

int()long() 內建函式現在將接受“0o”和“0b”字首,當請求 base-8 或 base-2 時,或者當 base 引數為零時(表示應從字串確定使用的基數)。

>>> int ('0o52', 0)
42
>>> int('1101', 2)
13
>>> int('0b1101', 2)
13
>>> int('0b1101', 0)
13

參見

PEP 3127 - 整數字面量支援和語法

PEP 由 Patrick Maupin 撰寫;由 Eric Smith 反向移植到 2.6。

PEP 3129: 類裝飾器

裝飾器已從函式擴充套件到類。現在可以合法地編寫:

@foo
@bar
class A:
  pass

這等價於:

class A:
  pass

A = foo(bar(A))

參見

PEP 3129 - 類裝飾器

PEP 由 Collin Winter 撰寫。

PEP 3141: 數字的型別層次結構

Python 3.0 增加了幾個受 Scheme 數字塔啟發的數字型別的抽象基類。這些類被反向移植到 2.6 作為 numbers 模組。

最通用的 ABC 是 Number。它根本不定義任何操作,只為了透過 isinstance(obj, Number) 檢查物件是否為數字而存在。

ComplexNumber 的子類。複數可以進行加法、減法、乘法、除法和乘方等基本操作,並且您可以檢索實部和虛部並獲取複數的共軛。Python 的內建 complex 型別是 Complex 的一個實現。

Real 進一步派生自 Complex,並添加了只作用於實數的操作:floor()trunc()、舍入、取模 N 的餘數、地板除法和比較。

Rational 數字派生自 Real,具有 numeratordenominator 屬性,並且可以轉換為浮點數。Python 2.6 在 fractions 模組中添加了一個簡單的有理數類 Fraction。(它被稱為 Fraction 而不是 Rational 以避免與 numbers.Rational 發生命名衝突。)

Integral 數字派生自 Rational,並且可以使用 <<>> 進行左右位移,使用 &| 等位運算進行組合,並且可以用作陣列索引和切片邊界。

在 Python 3.0 中,PEP 稍微重新定義了現有的內建函式 round()math.floor()math.ceil(),並添加了一個新的函式 math.trunc(),它已被反向移植到 Python 2.6。math.trunc() 向零舍入,返回函式引數與零之間最接近的 Integral

參見

PEP 3141 - 數字的型別層次結構

PEP 由 Jeffrey Yasskin 撰寫。

Scheme 的數值塔,來自 Guile 手冊。

Scheme 的數字資料型別,來自 R5RS Scheme 規範。

fractions 模組

為了完善數值型別的層次結構,fractions 模組提供了一個有理數類。有理數將其值儲存為分子和分母組成的真分數,可以精確表示像 2/3 這樣的數字,而浮點數只能近似表示。

Fraction 建構函式接受兩個 Integral 值,它們將作為結果分數的分子和分母。

>>> from fractions import Fraction
>>> a = Fraction(2, 3)
>>> b = Fraction(2, 5)
>>> float(a), float(b)
(0.66666666666666663, 0.40000000000000002)
>>> a+b
Fraction(16, 15)
>>> a/b
Fraction(5, 3)

對於將浮點數轉換為有理數,float 型別現在有一個 as_integer_ratio() 方法,該方法返回計算結果為相同浮點值的分數的分子和分母。

>>> (2.5) .as_integer_ratio()
(5, 2)
>>> (3.1415) .as_integer_ratio()
(7074029114692207L, 2251799813685248L)
>>> (1./3) .as_integer_ratio()
(6004799503160661L, 18014398509481984L)

請注意,只能透過浮點數近似的值(例如 1./3)不會簡化為被近似的數字;該分數試圖精確匹配浮點值。

fractions 模組基於 Sjoerd Mullender 的實現,該實現長期存在於 Python 的 Demo/classes/ 目錄中。此實現由 Jeffrey Yasskin 大幅更新。

其他語言更改

對核心 Python 語言做了一些較小的更改

  • 包含 __main__.py 檔案的目錄和 zip 存檔現在可以透過將其名稱傳遞給直譯器來直接執行。該目錄或 zip 存檔會自動作為第一個條目插入到 sys.path 中。(由 Andy Chu 提出並初步修補,隨後由 Phillip J. Eby 和 Nick Coghlan 修訂;bpo-1739468。)

  • hasattr() 函式以前會捕獲並忽略所有錯誤,假設它們表示 __getattr__() 方法以某種方式失敗,因此 hasattr() 的返回值將為 False。但是,此邏輯不應應用於 KeyboardInterruptSystemExit;Python 2.6 將不再在 hasattr() 遇到此類異常時將其丟棄。(由 Benjamin Peterson 修復;bpo-2196。)

  • 當使用 ** 語法呼叫函式以提供關鍵字引數時,不再需要使用 Python 字典;現在任何對映都可以工作。

    >>> def f(**kw):
    ...    print sorted(kw)
    ...
    >>> ud=UserDict.UserDict()
    >>> ud['a'] = 1
    >>> ud['b'] = 'string'
    >>> f(**ud)
    ['a', 'b']
    

    (由 Alexander Belopolsky 貢獻;bpo-1686487。)

    現在,在函式呼叫中 *args 引數之後提供關鍵字引數也合法了。

    >>> def f(*args, **kw):
    ...     print args, kw
    ...
    >>> f(1,2,3, *(4,5,6), keyword=13)
    (1, 2, 3, 4, 5, 6) {'keyword': 13}
    

    以前這會導致語法錯誤。(由 Amaury Forgeot d'Arc 貢獻;bpo-3473。)

  • 一個新的內建函式 next(iterator, [default]) 返回指定迭代器的下一個專案。如果提供了 default 引數,當 iterator 已耗盡時將返回它;否則,將引發 StopIteration 異常。(在 bpo-2719 中反向移植。)

  • 元組現在具有 index()count() 方法,與列表型別的 index()count() 方法匹配。

    >>> t = (0,1,2,3,4,0,1,2)
    >>> t.index(3)
    3
    >>> t.count(0)
    2
    

    (由 Raymond Hettinger 貢獻)

  • 內建型別現在改進了對擴充套件切片語法的支援,接受 (start, stop, step) 的各種組合。以前,支援是部分的,並且某些邊緣情況不起作用。(由 Thomas Wouters 實現。)

  • 屬性現在有三個屬性:gettersetterdeleter,它們是裝飾器,為現有屬性新增 getter、setter 或 deleter 函式提供了有用的快捷方式。您可以這樣使用它們:

    class C(object):
        @property
        def x(self):
            return self._x
    
        @x.setter
        def x(self, value):
            self._x = value
    
        @x.deleter
        def x(self):
            del self._x
    
    class D(C):
        @C.x.getter
        def x(self):
            return self._x * 2
    
        @x.setter
        def x(self, value):
            self._x = value / 2
    
  • 內建集合型別的幾個方法現在接受多個可迭代物件:intersection()intersection_update()union()update()difference()difference_update()

    >>> s=set('1234567890')
    >>> s.intersection('abc123', 'cdf246')  # Intersection between all inputs
    set(['2'])
    >>> s.difference('246', '789')
    set(['1', '0', '3', '5'])
    

    (由 Raymond Hettinger 貢獻。)

  • 添加了許多浮點功能。float() 函式現在將字串 nan 轉換為 IEEE 754 非數字值,並將 +inf-inf 轉換為正無窮或負無窮。這適用於任何具有 IEEE 754 語義的平臺。(由 Christian Heimes 貢獻;bpo-1635。)

    math 模組中的其他函式,isinf()isnan(),如果其浮點引數是無窮大或非數字,則返回 True。(bpo-1640

    添加了轉換函式以將浮點數轉換為十六進位制字串(bpo-3008)。這些函式將浮點數轉換為字串表示形式,反之亦然,而不會引入十進位制和二進位制之間轉換的舍入誤差。浮點數有一個 hex() 方法,該方法返回字串表示形式,float.fromhex() 方法將字串轉換回數字。

    >>> a = 3.75
    >>> a.hex()
    '0x1.e000000000000p+1'
    >>> float.fromhex('0x1.e000000000000p+1')
    3.75
    >>> b=1./3
    >>> b.hex()
    '0x1.5555555555555p-2'
    
  • 一個數值上的細節:在支援帶符號零(-0 和 +0)的系統上,從兩個浮點數建立複數時,complex() 建構函式現在將保留零的符號。(由 Mark T. Dickinson 修復;bpo-1507。)

  • 從父類繼承 __hash__() 方法的類可以將 __hash__ = None 設定為指示該類不可雜湊。這將使 hash(obj) 引發 TypeError,並且該類將不被指示為實現 Hashable ABC。

    當您定義了透過值而不是透過標識來比較物件的 __cmp__()__eq__() 方法時,您應該這樣做。所有物件都有一個預設的雜湊方法,它使用 id(obj) 作為雜湊值。沒有簡潔的方法可以刪除從父類繼承的 __hash__() 方法,因此將 None 賦值作為覆蓋實現。在 C 級別,擴充套件可以將 tp_hash 設定為 PyObject_HashNotImplemented()。(由 Nick Coghlan 和 Amaury Forgeot d'Arc 修復;bpo-2235。)

  • GeneratorExit 異常現在是 BaseException 的子類,而不是 Exception。這意味著執行 except Exception: 的異常處理程式不會無意中捕獲 GeneratorExit。(由 Chad Austin 貢獻;bpo-1537。)

  • 生成器物件現在有一個 gi_code 屬性,它指向支援該生成器的原始程式碼物件。(由 Collin Winter 貢獻;bpo-1473257。)

  • 內建函式 compile() 現在接受關鍵字引數和位置引數。(由 Thomas Wouters 貢獻;bpo-1444529。)

  • complex() 建構函式現在接受包含帶括號複數的字串,這意味著 complex(repr(cplx)) 現在將往返值。例如,complex('(3+4j)') 現在返回值 (3+4j)。(bpo-1491866

  • 字串的 translate() 方法現在接受 None 作為翻譯表引數,這被視為恆等變換。這使得僅刪除字元的操作更容易執行。(由 Bengt Richter 貢獻,由 Raymond Hettinger 實現;bpo-1193128。)

  • 內建函式 dir() 現在會檢查它接收到的物件上的 __dir__() 方法。此方法必須返回一個包含物件有效屬性名稱的字串列表,並允許物件控制 dir() 生成的值。具有 __getattr__()__getattribute__() 方法的物件可以使用此方法來宣傳它們將遵守的偽屬性。(bpo-1591665

  • 例項方法物件現在具有表示方法所包含的物件和函式的新屬性;im_self 的新同義詞是 __self__im_func 也可作為 __func__ 使用。舊名稱在 Python 2.6 中仍然支援,但在 3.0 中已移除。

  • 一個不明顯的改變:當您在 class 語句中使用 locals() 函式時,生成的字典不再返回自由變數。(在這種情況下,自由變數是 class 語句中引用但不是類屬性的變數。)

最佳化

  • warnings 模組已用 C 語言重寫。這使得可以從解析器呼叫警告,並且還可以使直譯器的啟動更快。(由 Neal Norwitz 和 Brett Cannon 貢獻;bpo-1631171。)

  • 型別物件現在有一個方法快取,可以減少查詢特定類的正確方法實現所需的工作;一旦快取,直譯器就不需要遍歷基類來確定要呼叫的正確方法。如果基類或類本身被修改,快取將被清除,因此即使在 Python 的動態特性面前,快取也應保持正確。(原始最佳化由 Armin Rigo 實現,Kevin Jacobs 為 Python 2.6 更新;bpo-1700288。)

    預設情況下,此更改僅應用於 Python 核心中包含的型別。擴充套件模組可能不一定與此快取相容,因此它們必須明確地將 Py_TPFLAGS_HAVE_VERSION_TAG 新增到模組的 tp_flags 欄位以啟用方法快取。(為了與方法快取相容,擴充套件模組的程式碼不能直接訪問和修改其實現的任何型別的 tp_dict 成員。大多數模組不這樣做,但 Python 直譯器無法確定這一點。有關討論,請參閱 bpo-1878。)

  • 使用關鍵字引數的函式呼叫透過快速指標比較顯著加快,通常可以節省完整的字串比較時間。(由 Raymond Hettinger 貢獻,最初由 Antoine Pitrou 實現後;bpo-1819。)

  • 由於 Need For Speed 衝刺的工作,struct 模組中的所有函式都已用 C 語言重寫。(由 Raymond Hettinger 貢獻。)

  • 一些標準內建型別現在在其型別物件中設定了一個位。這加快了檢查物件是否是這些型別之一的子類的速度。(由 Neal Norwitz 貢獻。)

  • Unicode 字串現在使用更快的程式碼來檢測空白和換行符;這使 split() 方法的速度提高了約 25%,splitlines() 提高了 35%。(由 Antoine Pitrou 貢獻。)透過對 Unicode 字串資料使用 pymalloc,記憶體使用量減少了。

  • with 語句現在將 __exit__() 方法儲存在堆疊上,從而實現小幅加速。(由 Jeffrey Yasskin 實現。)

  • 為了減少記憶體使用,垃圾回收器現在將在垃圾回收最高代物件時清除內部自由列表。這可能會更快地將記憶體返回給作業系統。

直譯器更改

兩個命令列選項已保留供其他 Python 實現使用。-J 開關已保留供 Jython 使用,用於 Jython 特定的選項,例如傳遞給底層 JVM 的開關。-X 已保留用於特定 Python 實現(如 CPython、Jython 或 IronPython)的選項。如果這兩個選項中的任何一個與 Python 2.6 一起使用,直譯器將報告該選項當前未使用。

現在可以透過向 Python 直譯器提供 -B 開關,或者在執行直譯器之前設定 PYTHONDONTWRITEBYTECODE 環境變數,來阻止 Python 寫入 .pyc.pyo 檔案。此設定作為 sys.dont_write_bytecode 變數可供 Python 程式使用,Python 程式碼可以更改此值以修改直譯器的行為。(由 Neal Norwitz 和 Georg Brandl 貢獻。)

可以透過在執行直譯器之前設定 PYTHONIOENCODING 環境變數來指定標準輸入、輸出和標準錯誤使用的編碼。該值應為 <encoding><encoding>:<errorhandler> 形式的字串。encoding 部分指定編碼名稱,例如 utf-8latin-1;可選的 errorhandler 部分指定如何處理編碼無法處理的字元,應為“error”、“ignore”或“replace”之一。(由 Martin von Löwis 貢獻。)

新增和改進的模組

與每個版本一樣,Python 的標準庫也獲得了許多增強和錯誤修復。以下是按模組名稱字母順序排序的最值得注意的更改的部分列表。有關更完整的更改列表,請查閱原始碼樹中的 Misc/NEWS 檔案,或檢視 Subversion 日誌以獲取所有詳細資訊。

  • asyncoreasynchat 模組再次積極維護,並應用了許多補丁和錯誤修復。(由 Josiah Carlson 維護;參見 bpo-1736190 獲取其中一個補丁。)

  • bsddb 模組也有了一個新的維護者 Jesús Cea Avión,並且該包現在作為一個獨立的包提供。該包的網頁是 www.jcea.es/programacion/pybsddb.htm。計劃是在 Python 3.0 中從標準庫中刪除該包,因為它的釋出頻率比 Python 更頻繁。

    bsddb.dbshelve 模組現在使用可用的最高醃製協議,而不是將自己限制在協議 1。(由 W. Barnes 貢獻。)

  • cgi 模組現在將從 HTTP POST 請求的查詢字串中讀取變數。這使得可以使用包含查詢字串(如“/cgi-bin/add.py?category=1”)的 URL 進行表單操作。(由 Alexandre Fiori 和 Nubis 貢獻;bpo-1817。)

    parse_qs()parse_qsl() 函式已從 cgi 模組遷移到 urlparse 模組。cgi 模組中仍然可用的版本將在 2.6 中觸發 PendingDeprecationWarning 訊息(bpo-600362)。

  • cmath 模組進行了廣泛修訂,由 Mark Dickinson 和 Christian Heimes 貢獻。添加了五個新函式:

    • polar() 將複數轉換為極座標形式,返回複數的模和幅角。

    • rect() 執行相反的操作,將模和幅角對轉換回相應的複數。

    • phase() 返回複數的幅角(也稱為角度)。

    • isnan() 如果其引數的實部或虛部是 NaN,則返回 True。

    • isinf() 如果其引數的實部或虛部是無窮大,則返回 True。

    修訂版還提高了 cmath 模組的數值穩健性。對於所有函式,結果的實部和虛部在可能的情況下都精確到幾個最低有效位(ulps)以內。有關詳細資訊,請參閱 bpo-1381asinh()atanh()atan() 的分支割也已更正。

    模組的測試已大大擴充套件;近 2000 個新的測試用例對代數函式進行了測試。

    在 IEEE 754 平臺上,cmath 模組現在以與 C99 標準附件“G”一致的方式處理 IEEE 754 特殊值和浮點異常。

  • collections 模組中的新資料型別:namedtuple(typename, fieldnames) 是一個工廠函式,它建立標準元組的子類,其欄位可以透過名稱和索引訪問。例如:

    >>> var_type = collections.namedtuple('variable',
    ...             'id name type size')
    >>> # Names are separated by spaces or commas.
    >>> # 'id, name, type, size' would also work.
    >>> var_type._fields
    ('id', 'name', 'type', 'size')
    
    >>> var = var_type(1, 'frequency', 'int', 4)
    >>> print var[0], var.id    # Equivalent
    1 1
    >>> print var[2], var.type  # Equivalent
    int int
    >>> var._asdict()
    {'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
    >>> v2 = var._replace(name='amplitude')
    >>> v2
    variable(id=1, name='amplitude', type='int', size=4)
    

    標準庫中返回元組的幾個地方已修改為返回 namedtuple() 例項。例如,Decimal.as_tuple() 方法現在返回一個具有 signdigitsexponent 欄位的命名元組。

    (由 Raymond Hettinger 貢獻。)

  • collections 模組的另一個變化是 deque 型別現在支援可選的 maxlen 引數;如果提供,deque 的大小將限制為不超過 maxlen 個專案。向已滿的 deque 新增更多專案會導致舊專案被丟棄。

    >>> from collections import deque
    >>> dq=deque(maxlen=3)
    >>> dq
    deque([], maxlen=3)
    >>> dq.append(1); dq.append(2); dq.append(3)
    >>> dq
    deque([1, 2, 3], maxlen=3)
    >>> dq.append(4)
    >>> dq
    deque([2, 3, 4], maxlen=3)
    

    (由 Raymond Hettinger 貢獻。)

  • Cookie 模組的 Morsel 物件現在支援 httponly 屬性。在某些瀏覽器中,設定了此屬性的 cookie 無法透過 JavaScript 程式碼訪問或操作。(由 Arvin Schnell 貢獻;bpo-1638033。)

  • curses 模組中的一個新視窗方法 chgat() 改變了單行上特定數量字元的顯示屬性。(由 Fabian Kreutz 貢獻。)

    # Boldface text starting at y=0,x=21
    # and affecting the rest of the line.
    stdscr.chgat(0, 21, curses.A_BOLD)
    

    curses.textpad 模組中的 Textbox 類現在支援插入模式和覆蓋模式編輯。透過在建立 Textbox 例項時為 insert_mode 引數提供真值來啟用插入模式。

  • datetime 模組的 strftime() 方法現在支援 %f 格式程式碼,該程式碼擴充套件為物件中微秒數,左側用零填充到六位。(由 Skip Montanaro 貢獻;bpo-1158。)

  • decimal 模組已更新到 通用十進位制規範 的 1.66 版。新功能包括一些基本數學函式的某些方法,例如 exp()log10()

    >>> Decimal(1).exp()
    Decimal("2.718281828459045235360287471")
    >>> Decimal("2.7182818").ln()
    Decimal("0.9999999895305022877376682436")
    >>> Decimal(1000).log10()
    Decimal("3")
    

    Decimal 物件的 as_tuple() 方法現在返回一個具有 signdigitsexponent 欄位的命名元組。

    (由 Facundo Batista 和 Mark Dickinson 實現。命名元組支援由 Raymond Hettinger 新增。)

  • difflib 模組的 SequenceMatcher 類現在返回表示匹配的命名元組,具有 absize 屬性。(由 Raymond Hettinger 貢獻。)

  • ftplib.FTP 類建構函式以及 connect() 方法中添加了一個可選的 timeout 引數,指定以秒為單位的超時時間。(由 Facundo Batista 新增。)此外,FTP 類的 storbinary()storlines() 現在接受一個可選的 callback 引數,該引數將在資料傳送後對每個資料塊進行呼叫。(由 Phil Schwartz 貢獻;bpo-1221598。)

  • 內建函式 reduce() 也可在 functools 模組中使用。在 Python 3.0 中,該內建函式已被刪除,reduce() 只能從 functools 獲得;目前沒有計劃在 2.x 系列中刪除該內建函式。(由 Christian Heimes 修補;bpo-1739906。)

  • 在可能的情況下,getpass 模組現在將使用 /dev/tty 列印提示訊息並讀取密碼,回退到標準錯誤和標準輸入。如果密碼可能被回顯到終端,則在顯示提示之前列印警告。(由 Gregory P. Smith 貢獻。)

  • 如果使用了 Unicode 路徑並且目錄中匹配了 Unicode 檔名,則 glob.glob() 函式現在可以返回 Unicode 檔名。(bpo-1001604

  • heapq 模組中的新函式 merge(iter1, iter2, ...),接受任意數量的按排序順序返回資料的可迭代物件,並返回一個新的生成器,該生成器也按排序順序返回所有迭代器的內容。例如:

    >>> list(heapq.merge([1, 3, 5, 9], [2, 8, 16]))
    [1, 2, 3, 5, 8, 9, 16]
    

    另一個新函式 heappushpop(heap, item)item 推入 heap,然後彈出並返回最小的項。這比呼叫 heappush() 然後呼叫 heappop() 更高效。

    heapq 現在實現為只使用小於比較,而不是它以前使用的小於或等於比較。這使得 heapq 對型別的使用與 list.sort() 方法匹配。(由 Raymond Hettinger 貢獻。)

  • httplib.HTTPConnectionHTTPSConnection 類建構函式中添加了一個可選的 timeout 引數,指定以秒為單位的超時時間。(由 Facundo Batista 新增。)

  • inspect 模組的大多數函式,例如 getmoduleinfo()getargs(),現在返回命名元組。除了像元組一樣行為外,返回值的元素也可以作為屬性訪問。(由 Raymond Hettinger 貢獻。)

    模組中的一些新函式包括 isgenerator()isgeneratorfunction()isabstract()

  • itertools 模組獲得了幾個新函式。

    izip_longest(iter1, iter2, ...[, fillvalue]) 從每個元素建立元組;如果某些可迭代物件比其他物件短,則缺失的值設定為 fillvalue。例如:

    >>> tuple(itertools.izip_longest([1,2,3], [1,2,3,4,5]))
    ((1, 1), (2, 2), (3, 3), (None, 4), (None, 5))
    

    product(iter1, iter2, ..., [repeat=N]) 返回所提供可迭代物件的笛卡爾積,這是一組元組,包含從每個可迭代物件返回的元素的每種可能組合。

    >>> list(itertools.product([1,2,3], [4,5,6]))
    [(1, 4), (1, 5), (1, 6),
     (2, 4), (2, 5), (2, 6),
     (3, 4), (3, 5), (3, 6)]
    

    可選的 repeat 關鍵字引數用於將可迭代物件或一組可迭代物件與自身取乘積,重複 N 次。對於單個可迭代引數,返回 N 元組:

    >>> list(itertools.product([1,2], repeat=3))
    [(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
     (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]
    

    對於兩個可迭代物件,返回 2N 元組。

    >>> list(itertools.product([1,2], [3,4], repeat=2))
    [(1, 3, 1, 3), (1, 3, 1, 4), (1, 3, 2, 3), (1, 3, 2, 4),
     (1, 4, 1, 3), (1, 4, 1, 4), (1, 4, 2, 3), (1, 4, 2, 4),
     (2, 3, 1, 3), (2, 3, 1, 4), (2, 3, 2, 3), (2, 3, 2, 4),
     (2, 4, 1, 3), (2, 4, 1, 4), (2, 4, 2, 3), (2, 4, 2, 4)]
    

    combinations(iterable, r)iterable 的元素中返回長度為 r 的子序列。

    >>> list(itertools.combinations('123', 2))
    [('1', '2'), ('1', '3'), ('2', '3')]
    >>> list(itertools.combinations('123', 3))
    [('1', '2', '3')]
    >>> list(itertools.combinations('1234', 3))
    [('1', '2', '3'), ('1', '2', '4'),
     ('1', '3', '4'), ('2', '3', '4')]
    

    permutations(iter[, r]) 返回 iterable 元素的長度為 r 的所有排列。如果未指定 r,則預設為可迭代物件生成的元素數量。

    >>> list(itertools.permutations([1,2,3,4], 2))
    [(1, 2), (1, 3), (1, 4),
     (2, 1), (2, 3), (2, 4),
     (3, 1), (3, 2), (3, 4),
     (4, 1), (4, 2), (4, 3)]
    

    itertools.chain(*iterables)itertools 中一個現有函式,在 Python 2.6 中獲得了一個新的建構函式。itertools.chain.from_iterable(iterable) 接受一個應返回其他可迭代物件的單個可迭代物件。chain() 將返回第一個可迭代物件的所有元素,然後是第二個可迭代物件的所有元素,依此類推。

    >>> list(itertools.chain.from_iterable([[1,2,3], [4,5,6]]))
    [1, 2, 3, 4, 5, 6]
    

    (均由 Raymond Hettinger 貢獻。)

  • logging 模組的 FileHandler 類及其子類 WatchedFileHandlerRotatingFileHandlerTimedRotatingFileHandler 現在其建構函式中有一個可選的 delay 引數。如果 delay 為 True,則日誌檔案的開啟將延遲到第一次呼叫 emit() 時進行。(由 Vinay Sajip 貢獻。)

    TimedRotatingFileHandler 也有一個 utc 建構函式引數。如果該引數為 True,則在確定午夜發生時間和生成檔名時將使用 UTC 時間;否則將使用本地時間。

  • math 模組中添加了幾個新函式:

    • isinf()isnan() 分別確定給定的浮點數是否為(正或負)無窮大或 NaN(非數字)。

    • copysign() 複製 IEEE 754 數字的符號位,返回 x 的絕對值與 y 的符號位組合。例如,math.copysign(1, -0.0) 返回 -1.0。(由 Christian Heimes 貢獻。)

    • factorial() 計算一個數字的階乘。(由 Raymond Hettinger 貢獻;bpo-2138。)

    • fsum() 將可迭代物件中的數字流相加,並透過使用部分和來謹慎避免精度損失。(由 Jean Brouwers、Raymond Hettinger 和 Mark Dickinson 貢獻;bpo-2819。)

    • acosh()asinh()atanh() 計算反雙曲函式。

    • log1p() 返回 1+x 的自然對數(以 e 為底)。

    • trunc() 將數字向零舍入,返回函式引數與零之間最接近的 Integral。作為 PEP 3141 數字型別層次結構 的反向移植的一部分新增。

  • math 模組已改進,以提供更跨平臺一致的行為,尤其是在處理浮點異常和 IEEE 754 特殊值方面。

    在可能的情況下,該模組遵循 C99 標準關於 754 特殊值的建議。例如,sqrt(-1.) 現在在幾乎所有平臺上都應該產生 ValueError,而 sqrt(float('NaN')) 在所有 IEEE 754 平臺上都應該返回 NaN。如果 C99 標準附件“F”建議發出“除以零”或“無效”訊號,Python 將引發 ValueError。如果 C99 標準附件“F”建議發出“溢位”訊號,Python 將引發 OverflowError。(參見 bpo-711019bpo-1640。)

    (由 Christian Heimes 和 Mark Dickinson 貢獻。)

  • mmap 物件現在有一個 rfind() 方法,該方法從字串末尾開始向後搜尋子字串。find() 方法也獲得了一個 end 引數,用於指定停止搜尋的索引。(由 John Lenton 貢獻。)

  • operator 模組獲得了一個 methodcaller() 函式,該函式接受一個名稱和一組可選引數,返回一個可呼叫物件,該物件將在傳遞給它的任何引數上呼叫命名函式。例如:

    >>> # Equivalent to lambda s: s.replace('old', 'new')
    >>> replacer = operator.methodcaller('replace', 'old', 'new')
    >>> replacer('old wine in old bottles')
    'new wine in new bottles'
    

    (由 Georg Brandl 貢獻,源於 Gregory Petrosyan 的建議。)

    attrgetter() 函式現在接受點分名稱並執行相應的屬性查詢。

    >>> inst_name = operator.attrgetter(
    ...        '__class__.__name__')
    >>> inst_name('')
    'str'
    >>> inst_name(help)
    '_Helper'
    

    (由 Georg Brandl 貢獻,源於 Barry Warsaw 的建議。)

  • os 模組現在封裝了幾個新的系統呼叫。fchmod(fd, mode)fchown(fd, uid, gid) 更改已開啟檔案的模式和所有權,lchmod(path, mode) 更改符號連結的模式。(由 Georg Brandl 和 Christian Heimes 貢獻。)

    chflags()lchflags() 是相應系統呼叫(如果可用)的封裝器,用於更改檔案上設定的標誌。stat 模組中定義了標誌值的常量;一些可能的值包括 UF_IMMUTABLE 表示檔案不可更改,UF_APPEND 表示資料只能追加到檔案中。(由 M. Levinson 貢獻。)

    os.closerange(low, high) 有效地關閉從 lowhigh 的所有檔案描述符,忽略任何錯誤且不包括 high 本身。此函式現在由 subprocess 模組使用,以加快程序啟動。(由 Georg Brandl 貢獻;bpo-1663329。)

  • os.environ 物件的 clear() 方法現在將使用 os.unsetenv() 取消設定環境變數,並清除物件的鍵。(由 Martin Horcicka 貢獻;bpo-1181。)

  • os.walk() 函式現在有一個 followlinks 引數。如果設定為 True,它將跟隨指向目錄的符號連結並訪問目錄內容。為了向後相容,該引數的預設值為 false。請注意,如果存在指向父目錄的符號連結,該函式可能會陷入無限遞迴。(bpo-1273829

  • os.path 模組中,splitext() 函式已更改為不對前導句點字元進行拆分。這在操作 Unix 的點檔案時會產生更好的結果。例如,os.path.splitext('.ipython') 現在返回 ('.ipython', '') 而不是 ('', '.ipython')。(bpo-1115886

    一個新函式 os.path.relpath(path, start='.'),返回從 start 路徑(如果提供)或從當前工作目錄到目標 path 的相對路徑。(由 Richard Barran 貢獻;bpo-1339796。)

    在 Windows 上,os.path.expandvars() 現在將展開“%var%”形式的環境變數,並且“~user”將擴充套件為使用者的主目錄路徑。(由 Josiah Carlson 貢獻;bpo-957650。)

  • pdb 模組提供的 Python 偵錯程式新增了一個命令:“run”會重新啟動正在除錯的 Python 程式,並且可以選擇性地為程式提供新的命令列引數。(由 Rocky Bernstein 貢獻;bpo-1393667。)

  • 用於開始除錯回溯的 pdb.post_mortem() 函式,如果未提供回溯,現在將使用 sys.exc_info() 返回的回溯。(由 Facundo Batista 貢獻;bpo-1106316。)

  • pickletools 模組現在有一個 optimize() 函式,它接受一個包含 pickle 的字串,並刪除一些未使用的操作碼,返回一個包含相同資料結構的較短 pickle。(由 Raymond Hettinger 貢獻。)

  • pkgutil 模組中添加了一個 get_data() 函式,該函式返回安裝的 Python 包中包含的資原始檔的內容。例如

    >>> import pkgutil
    >>> print pkgutil.get_data('test', 'exception_hierarchy.txt')
    BaseException
     +-- SystemExit
     +-- KeyboardInterrupt
     +-- GeneratorExit
     +-- Exception
          +-- StopIteration
          +-- StandardError
     ...
    

    (由 Paul Moore 貢獻;bpo-2439。)

  • pyexpat 模組的 Parser 物件現在允許設定其 buffer_size 屬性,以更改用於儲存字元資料的緩衝區大小。(由 Achim Gaedke 貢獻;bpo-1137。)

  • Queue 模組現在提供了以不同順序檢索條目的佇列變體。PriorityQueue 類將排隊的專案儲存在堆中並按優先順序順序檢索它們,而 LifoQueue 首先檢索最近新增的條目,這意味著它的行為類似於堆疊。(由 Raymond Hettinger 貢獻。)

  • random 模組的 Random 物件現在可以在 32 位系統上進行 pickled,並在 64 位系統上進行 unpickled,反之亦然。不幸的是,這一變化也意味著 Python 2.6 的 Random 物件不能在早期版本的 Python 上正確地 unpickled。(由 Shawn Ligocki 貢獻;bpo-1727780。)

    新的 triangular(low, high, mode) 函式返回遵循三角形分佈的隨機數。返回的值在 lowhigh 之間,不包括 high 本身,並且 mode 是分佈中最常出現的值。(由 Wladmir van der Laan 和 Raymond Hettinger 貢獻;bpo-1681432。)

  • re 模組執行的長時間正則表示式搜尋將檢查是否有訊號傳遞,因此耗時的搜尋現在可以中斷。(由 Josh Hoyt 和 Ralf Schmitt 貢獻;bpo-846388。)

    正則表示式模組是透過為微型正則表示式專用虛擬機器編譯位元組碼來實現的。不可信的程式碼可以直接建立惡意位元組碼字串並導致崩潰,因此 Python 2.6 包含了正則表示式位元組碼的驗證器。(由 Guido van Rossum 從 Google App Engine 的工作貢獻;bpo-3487。)

  • rlcompleter 模組的 Completer.complete() 方法現在將忽略在評估名稱時觸發的異常。(由 Lorenz Quack 修復;bpo-2250。)

  • sched 模組的 scheduler 例項現在有一個只讀的 queue 屬性,該屬性返回排程器佇列的內容,表示為具有欄位 (time, priority, action, argument) 的命名元組列表。(由 Raymond Hettinger 貢獻;bpo-1861。)

  • select 模組現在有 Linux epoll() 和 BSD kqueue() 系統呼叫的包裝函式。現有的 poll 物件中添加了 modify() 方法;pollobj.modify(fd, eventmask) 接受一個檔案描述符或檔案物件和一個事件掩碼,修改該檔案的記錄事件掩碼。(由 Christian Heimes 貢獻;bpo-1657。)

  • shutil.copytree() 函式現在有一個可選的 ignore 引數,它接受一個可呼叫物件。這個可呼叫物件將接收每個目錄路徑和目錄內容列表,並返回一個將被忽略(不復制)的名稱列表。

    shutil 模組還提供了 ignore_patterns() 函式,用於與此新引數一起使用。ignore_patterns() 接受任意數量的 glob 樣式模式,並返回一個可呼叫物件,該物件將忽略與這些模式中的任何一個匹配的檔案和目錄。以下示例複製目錄樹,但跳過 .svn 目錄和名稱以“~”結尾的 Emacs 備份檔案

    shutil.copytree('Doc/library', '/tmp/library',
                    ignore=shutil.ignore_patterns('*~', '.svn'))
    

    (由 Tarek Ziadé 貢獻;bpo-2663。)

  • 將訊號處理與 Tkinter 或 GTk+ 等 GUI 事件迴圈整合一直是個問題;大多數軟體最終會輪詢,每隔幾分之一秒喚醒一次,檢查是否發生了任何 GUI 事件。signal 模組現在可以使其更高效。呼叫 signal.set_wakeup_fd(fd) 會設定一個要使用的檔案描述符;當接收到訊號時,一個位元組會寫入該檔案描述符。還有一個 C 級函式 PySignal_SetWakeupFd()>,用於設定描述符。

    事件迴圈將透過開啟一個管道來建立兩個描述符,一個用於讀取,一個用於寫入。可寫描述符將傳遞給 set_wakeup_fd(),可讀描述符將透過 select()poll() 新增到事件迴圈監視的描述符列表中。接收到訊號後,將寫入一個位元組並喚醒主事件迴圈,從而避免了輪詢的需要。

    (由 Adam Olsen 貢獻;bpo-1583。)

    siginterrupt() 函式現在可以從 Python 程式碼中獲得,並允許更改訊號是否可以中斷系統呼叫。(由 Ralf Schmitt 貢獻。)

    setitimer()getitimer() 函式也已新增(如果可用)。setitimer() 允許設定間隔計時器,這些計時器將在指定時間(以實際時間、消耗的程序時間或組合的程序+系統時間測量)後向程序傳遞訊號。(由 Guilherme Polo 貢獻;bpo-2240。)

  • smtplib 模組現在支援透過 SSL 傳送 SMTP,這得益於 SMTP_SSL 類的新增。該類支援與現有 SMTP 類相同的介面。(由 Monty Taylor 貢獻。)兩個類建構函式都有一個可選的 timeout 引數,該引數指定初始連線嘗試的超時時間,以秒為單位。(由 Facundo Batista 貢獻。)

    模組中還添加了 LMTP 協議 (RFC 2033) 的實現。LMTP 在代理之間傳輸電子郵件時使用,這些代理不管理郵件佇列。(LMTP 由 Leif Hedstrom 實現;bpo-957003。)

    SMTP.starttls() 現在符合 RFC 3207,並會遺忘從伺服器獲得但並非來自 TLS 協商本身的任何資訊。(補丁由 Bill Fenner 貢獻;bpo-829951。)

  • socket 模組現在支援 TIPC (https://tipc.sourceforge.net/),這是一種高效能的非 IP 協議,專為叢集環境而設計。TIPC 地址是 4 或 5 元組。(由 Alberto Bertogli 貢獻;bpo-1646。)

    一個新的函式 create_connection() 接受一個地址並使用可選的超時值連線到它,返回連線的套接字物件。該函式還會查詢地址型別,並根據情況使用 IPv4 或 IPv6 連線到它。將您的程式碼更改為使用 create_connection() 而不是 socket(socket.AF_INET, ...) 可能就是使您的程式碼與 IPv6 相容所需的全部操作。

  • SocketServer 模組中的基類現在支援在由伺服器的 timeout 屬性指定的一段時間不活動後呼叫 handle_timeout() 方法。(由 Michael Pomraning 貢獻。)serve_forever() 方法現在接受一個可選的以秒為單位的輪詢間隔,控制伺服器檢查關機請求的頻率。(由 Pedro Werneck 和 Jeffrey Yasskin 貢獻;bpo-742598, bpo-1193577。)

  • 由 Gerhard Häring 維護的 sqlite3 模組已從 Python 2.5 中的 2.3.2 版本更新到 2.4.1 版本。

  • struct 模組現在支援 C99 _Bool 型別,使用格式字元 '?'。(由 David Remahl 貢獻。)

  • subprocess 模組提供的 Popen 物件現在具有 terminate()kill()send_signal() 方法。在 Windows 上,send_signal() 僅支援 SIGTERM 訊號,所有這些方法都是 Win32 API 函式 TerminateProcess() 的別名。(由 Christian Heimes 貢獻。)

  • sys 模組中的一個新變數 float_info 是一個物件,其中包含從 float.h 檔案中獲取的關於平臺浮點支援的資訊。此物件的屬性包括 mant_dig(尾數中的位數)、epsilon(1.0 與下一個可表示的最大值之間的最小差異)以及其他幾個。(由 Christian Heimes 貢獻;bpo-1534。)

    另一個新變數 dont_write_bytecode 控制 Python 在匯入模組時是否寫入任何 .pyc.pyo 檔案。如果此變數為 True,則不寫入編譯後的檔案。該變數在啟動時透過向 Python 直譯器提供 -B 開關,或在執行直譯器之前設定 PYTHONDONTWRITEBYTECODE 環境變數來初始化設定。Python 程式碼隨後可以更改此變數的值,以控制是否寫入位元組碼檔案。(由 Neal Norwitz 和 Georg Brandl 貢獻。)

    有關提供給 Python 直譯器的命令列引數的資訊可透過讀取 sys.flags 中可用命名元組的屬性獲得。例如,如果 Python 在詳細模式下執行,verbose 屬性為真;在除錯模式下,debug 為真等等。這些屬性都是隻讀的。(由 Christian Heimes 貢獻。)

    新增函式 getsizeof(),接受一個 Python 物件並返回該物件佔用的記憶體量,以位元組為單位。內建物件返回正確的結果;第三方擴充套件可能不會,但可以定義 __sizeof__() 方法以返回物件大小。(由 Robert Schuppenies 貢獻;bpo-2898。)

    現在可以透過呼叫 sys.getprofile()sys.gettrace() 來確定當前的分析器和跟蹤器函式。(由 Georg Brandl 貢獻;bpo-1648。)

  • tarfile 模組除了已經支援的 POSIX.1-1988 (ustar) 和 GNU tar 格式外,現在還支援 POSIX.1-2001 (pax) tarfile。預設格式是 GNU tar;使用 format 引數指定以不同格式開啟檔案

    tar = tarfile.open("output.tar", "w",
                       format=tarfile.PAX_FORMAT)
    

    新的 encodingerrors 引數指定了字元轉換的編碼和錯誤處理方案。'strict''ignore''replace' 是 Python 處理錯誤的三種標準方式;'utf-8' 是一個特殊值,它用 UTF-8 表示替換壞字元。(發生字元轉換是因為 PAX 格式支援 Unicode 檔名,預設為 UTF-8 編碼。)

    TarFile.add() 方法現在接受一個 exclude 引數,該引數是一個函式,可用於將某些檔名從存檔中排除。該函式必須接受一個檔名並返回 True(如果應排除該檔案)或 False(如果應存檔該檔案)。該函式應用於最初傳遞給 add() 的名稱以及遞迴新增目錄中的檔名。

    (所有更改均由 Lars Gustäbel 貢獻)。

  • telnetlib.Telnet 類建構函式中添加了一個可選的 timeout 引數,指定以秒為單位的超時時間。(由 Facundo Batista 新增。)

  • tempfile.NamedTemporaryFile 類通常在檔案關閉時刪除其建立的臨時檔案。現在可以透過向建構函式傳遞 delete=False 來更改此行為。(由 Damien Miller 貢獻;bpo-1537850。)

    一個新類 SpooledTemporaryFile 的行為類似於臨時檔案,但將其資料儲存在記憶體中,直到超出最大大小。達到該限制後,內容將被寫入磁碟上的臨時檔案。(由 Dustin J. Mitchell 貢獻。)

    NamedTemporaryFileSpooledTemporaryFile 類都作為上下文管理器工作,因此您可以編寫 with tempfile.NamedTemporaryFile() as tmp: ...。(由 Alexander Belopolsky 貢獻;bpo-2021。)

  • test.test_support 模組新增了許多用於編寫測試的上下文管理器。EnvironmentVarGuard() 是一個上下文管理器,它臨時更改環境變數並自動將其恢復為舊值。

    另一個上下文管理器 TransientResource 可以包圍對可能或可能不可用的資源的呼叫;它將捕獲並忽略指定異常列表。例如,網路測試在連線到外部網站時可能會忽略某些失敗

    with test_support.TransientResource(IOError,
                                    errno=errno.ETIMEDOUT):
        f = urllib.urlopen('https://sf.net')
        ...
    

    最後,check_warnings() 重置 warning 模組的警告過濾器,並返回一個將記錄所有觸發的警告訊息的物件(bpo-3781

    with test_support.check_warnings() as wrec:
        warnings.simplefilter("always")
        # ... code that triggers a warning ...
        assert str(wrec.message) == "function is outdated"
        assert len(wrec.warnings) == 1, "Multiple warnings raised"
    

    (由 Brett Cannon 貢獻。)

  • textwrap 模組現在可以透過將 drop_whitespace=False 指定為引數來保留新建立行開頭和結尾處的現有空白

    >>> S = """This  sentence  has a bunch   of
    ...   extra   whitespace."""
    >>> print textwrap.fill(S, width=15)
    This  sentence
    has a bunch
    of    extra
    whitespace.
    >>> print textwrap.fill(S, drop_whitespace=False, width=15)
    This  sentence
      has a bunch
       of    extra
       whitespace.
    >>>
    

    (由 Dwayne Bailey 貢獻;bpo-1581073。)

  • threading 模組 API 正在更改為使用 daemon 等屬性,而不是 setDaemon()isDaemon() 方法,並且一些方法已重新命名為使用下劃線而不是駝峰式大小寫;例如,activeCount() 方法重新命名為 active_count()。該模組的 2.6 和 3.0 版本都支援相同的屬性和重新命名的方法,但不會刪除舊方法。Python 3.x 中舊 API 的棄用日期尚未確定;舊 API 不會在任何 2.x 版本中刪除。(由多人執行,其中最著名的是 Benjamin Peterson。)

    threading 模組的 Thread 物件獲得了一個 ident 屬性,該屬性返回執行緒的識別符號,一個非零整數。(由 Gregory P. Smith 貢獻;bpo-2871。)

  • timeit 模組現在接受可呼叫物件以及字串作為計時語句和設定程式碼。添加了兩個用於建立 Timer 例項的便利函式:repeat(stmt, setup, time, repeat, number)timeit(stmt, setup, time, number) 建立一個例項並呼叫相應的方法。(由 Erik Demaine 貢獻;bpo-1533909。)

  • Tkinter 模組現在接受列表和元組作為選項,在將結果值傳遞給 Tcl/Tk 之前,用空格分隔元素。(由 Guilherme Polo 貢獻;bpo-2906。)

  • 由 Gregor Lingl 大幅增強了海龜繪圖模組 turtle。該模組的新功能包括

    • 更好的海龜移動和旋轉動畫。

    • 使用新的 delay()tracer()speed() 方法控制海龜運動。

    • 能夠為海龜設定新形狀並定義新座標系。

    • 海龜現在有一個 undo() 方法,可以回滾操作。

    • 對滑鼠和鍵盤活動等輸入事件做出反應的簡單支援,從而可以編寫簡單的遊戲。

    • turtle.cfg 檔案可用於自定義海龜螢幕的起始外觀。

    • 模組的 docstrings 可以替換為已翻譯成其他語言的新 docstrings。

    (bpo-1513695)

  • urllib.urlopen 函式和 urllib.ftpwrapper 類建構函式以及 urllib2.urlopen 函式中添加了一個可選的 timeout 引數。該引數指定以秒為單位的超時時間。例如

    >>> u = urllib2.urlopen("http://slow.example.com",
                            timeout=3)
    Traceback (most recent call last):
      ...
    urllib2.URLError: <urlopen error timed out>
    >>>
    

    (由 Facundo Batista 新增。)

  • unicodedata 模組提供的 Unicode 資料庫已更新到 5.1.0 版本。(由 Martin von Löwis 更新;bpo-3811。)

  • warnings 模組的 formatwarning()showwarning() 新增了一個可選的 line 引數,可用於提供原始碼行。(作為 bpo-1631171 的一部分新增,該更改重新實現了 warnings 模組的部分 C 程式碼。)

    一個新函式 catch_warnings() 是一個上下文管理器,旨在用於測試目的,它允許您臨時修改警告過濾器,然後恢復它們的原始值(bpo-3781)。

  • XML-RPC SimpleXMLRPCServerDocXMLRPCServer 類現在可以透過將 False 作為 bind_and_activate 建構函式引數來阻止它們立即開啟並繫結到其套接字。這可用於在呼叫 server_bind()server_activate() 方法以開啟套接字並開始偵聽連線之前修改例項的 allow_reuse_address 屬性。(由 Peter Parente 貢獻;bpo-1599845。)

    SimpleXMLRPCServer 還有一個 _send_traceback_header 屬性;如果為 True,則異常和格式化的回溯將作為 HTTP 頭部“X-Exception”和“X-Traceback”返回。此功能僅用於除錯目的,不應用於生產伺服器,因為回溯可能會洩露密碼或其他敏感資訊。(由 Alan McIntyre 作為他 2007 年 Google Summer of Code 專案的一部分貢獻。)

  • xmlrpclib 模組不再自動將 datetime.datedatetime.time 轉換為 xmlrpclib.DateTime 型別;這種轉換語義不一定適用於所有應用程式。使用 xmlrpclib 的程式碼應該轉換 datetime 例項。(bpo-1330538)該程式碼還可以處理 1900 年之前的日期(由 Ralf Schmitt 貢獻;bpo-2014)以及透過在 XML-RPC 響應中使用 <i8> 表示的 64 位整數(由 Riku Lindblad 貢獻;bpo-2985)。

  • zipfile 模組的 ZipFile 類現在具有 extract()extractall() 方法,可以將單個檔案或存檔中的所有檔案解壓縮到當前目錄或指定目錄

    z = zipfile.ZipFile('python-251.zip')
    
    # Unpack a single file, writing it relative
    # to the /tmp directory.
    z.extract('Python/sysmodule.c', '/tmp')
    
    # Unpack all the files in the archive.
    z.extractall()
    

    (由 Alan McIntyre 貢獻;bpo-467924。)

    open()read()extract() 方法現在可以接受檔名或 ZipInfo 物件。當存檔中意外包含重複檔名時,這非常有用。(由 Graham Horler 貢獻;bpo-1775025。)

    最後,zipfile 現在支援使用 Unicode 檔名進行存檔檔案。(由 Alexey Borzenkov 貢獻;bpo-1734346。)

ast 模組

ast 模組提供了 Python 程式碼的抽象語法樹表示,Armin Ronacher 貢獻了一組執行各種常見任務的輔助函式。這些函式將對 HTML 模板包、程式碼分析器和處理 Python 程式碼的類似工具非常有用。

parse() 函式接受一個表示式並返回一個 AST。dump() 函式輸出樹的表示,適用於除錯

import ast

t = ast.parse("""
d = {}
for i in 'abcdefghijklm':
    d[i + i] = ord(i) - ord('a') + 1
print d
""")
print ast.dump(t)

這會輸出一個深度巢狀的樹

Module(body=[
  Assign(targets=[
    Name(id='d', ctx=Store())
   ], value=Dict(keys=[], values=[]))
  For(target=Name(id='i', ctx=Store()),
      iter=Str(s='abcdefghijklm'), body=[
    Assign(targets=[
      Subscript(value=
        Name(id='d', ctx=Load()),
          slice=
          Index(value=
            BinOp(left=Name(id='i', ctx=Load()), op=Add(),
             right=Name(id='i', ctx=Load()))), ctx=Store())
     ], value=
     BinOp(left=
      BinOp(left=
       Call(func=
        Name(id='ord', ctx=Load()), args=[
          Name(id='i', ctx=Load())
         ], keywords=[], starargs=None, kwargs=None),
       op=Sub(), right=Call(func=
        Name(id='ord', ctx=Load()), args=[
          Str(s='a')
         ], keywords=[], starargs=None, kwargs=None)),
       op=Add(), right=Num(n=1)))
    ], orelse=[])
   Print(dest=None, values=[
     Name(id='d', ctx=Load())
   ], nl=True)
 ])

literal_eval() 方法接受一個字串或一個表示字面表示式的 AST,解析並評估它,然後返回結果值。字面表示式是一個只包含字串、數字、字典等,但不包含語句或函式呼叫的 Python 表示式。如果您需要評估一個表示式但不能接受使用 eval() 呼叫的安全風險,literal_eval() 將安全地處理它

>>> literal = '("a", "b", {2:4, 3:8, 1:2})'
>>> print ast.literal_eval(literal)
('a', 'b', {1: 2, 2: 4, 3: 8})
>>> print ast.literal_eval('"a" + "b"')
Traceback (most recent call last):
  ...
ValueError: malformed string

該模組還包括 NodeVisitorNodeTransformer 類,用於遍歷和修改 AST,以及用於常見轉換(如更改行號)的函式。

future_builtins 模組

Python 3.0 對內建函式庫進行了許多更改,其中大多數更改無法在 Python 2.x 系列中引入,因為它們會破壞相容性。future_builtins 模組提供了這些內建函式的版本,可以在編寫 3.0 相容程式碼時匯入。

此模組中的函式目前包括

  • ascii(obj):相當於 repr()。在 Python 3.0 中,repr() 將返回一個 Unicode 字串,而 ascii() 將返回一個純 ASCII 位元組字串。

  • filter(predicate, iterable), map(func, iterable1, ...): 3.0 版本返回迭代器,與 2.x 內建函式返回列表不同。

  • hex(value), oct(value): 這些版本不會呼叫 __hex__()__oct__() 方法,而是呼叫 __index__() 方法並將結果轉換為十六進位制或八進位制。oct() 將使用新的 0o 符號表示其結果。

json 模組:JavaScript 物件表示法

新的 json 模組支援在 JSON (Javascript Object Notation) 中編碼和解碼 Python 型別。JSON 是一種輕量級交換格式,常用於 Web 應用程式。有關 JSON 的更多資訊,請參閱 http://www.json.org

json 支援解碼和編碼大多數內建 Python 型別。以下示例編碼和解碼一個字典

>>> import json
>>> data = {"spam": "foo", "parrot": 42}
>>> in_json = json.dumps(data) # Encode the data
>>> in_json
'{"parrot": 42, "spam": "foo"}'
>>> json.loads(in_json) # Decode into a Python object
{"spam": "foo", "parrot": 42}

也可以編寫自己的解碼器和編碼器以支援更多型別。還支援 JSON 字串的漂亮列印。

json(最初名為 simplejson)由 Bob Ippolito 編寫。

plistlib 模組:一個屬性列表解析器

.plist 格式通常用於 Mac OS X,透過將基本資料型別(數字、字串、列表和字典)序列化為基於 XML 的格式來儲存。它類似於 XML-RPC 資料型別的序列化。

儘管主要用於 Mac OS X,但該格式沒有 Mac 特定的內容,並且 Python 實現適用於 Python 支援的任何平臺,因此 plistlib 模組已升級到標準庫。

使用模組很簡單

import sys
import plistlib
import datetime

# Create data structure
data_struct = dict(lastAccessed=datetime.datetime.now(),
                   version=1,
                   categories=('Personal','Shared','Private'))

# Create string containing XML.
plist_str = plistlib.writePlistToString(data_struct)
new_struct = plistlib.readPlistFromString(plist_str)
print data_struct
print new_struct

# Write data structure to a file and read it back.
plistlib.writePlist(data_struct, '/tmp/customizations.plist')
new_struct = plistlib.readPlist('/tmp/customizations.plist')

# read/writePlist accepts file-like objects as well as paths.
plistlib.writePlist(data_struct, sys.stdout)

ctypes 增強功能

Thomas Heller 繼續維護和增強 ctypes 模組。

ctypes 現在支援表示 C99 bool 型別的 c_bool 資料型別。(由 David Remahl 貢獻;bpo-1649190。)

ctypes 字串、緩衝區和陣列型別改進了對擴充套件切片語法的支援,其中提供了 (start, stop, step) 的各種組合。(由 Thomas Wouters 實現。)

所有 ctypes 資料型別現在都支援 from_buffer()from_buffer_copy() 方法,這些方法根據提供的緩衝區物件建立 ctypes 例項。from_buffer_copy() 複製物件的內容,而 from_buffer() 將共享相同的記憶體區域。

一個新的呼叫約定指示 ctypes 在每次包裝呼叫開始時清除 errno 或 Win32 LastError 變數。(由 Thomas Heller 實現;bpo-1798。)

您現在可以在函式呼叫後檢索 Unix errno 變數。建立包裝函式時,您可以將 use_errno=True 作為關鍵字引數提供給 DLL() 函式,然後呼叫模組級方法 set_errno()get_errno() 來設定和檢索錯誤值。

Win32 LastError 變數同樣受 DLL()OleDLL()WinDLL() 函式支援。您提供 use_last_error=True 作為關鍵字引數,然後呼叫模組級方法 set_last_error()get_last_error()

byref() 函式用於檢索指向 ctypes 例項的指標,現在有一個可選的 offset 引數,它是一個位元組計數,將新增到返回的指標中。

改進的 SSL 支援

Bill Janssen 透過新增一個新模組 ssl,該模組構建在 OpenSSL 庫之上,從而對 Python 2.6 的安全套接字層支援進行了廣泛改進。這個新模組提供了對協商協議、使用的 X.509 證書的更多控制,並且更好地支援用 Python 編寫 SSL 伺服器(而不是客戶端)。socket 模組中現有的 SSL 支援尚未移除,並繼續有效,儘管它將在 Python 3.0 中移除。

要使用新模組,必須首先以通常方式建立 TCP 連線,然後將其傳遞給 ssl.wrap_socket() 函式。可以指定是否需要證書,並透過呼叫 getpeercert() 方法獲取證書資訊。

參見

ssl 模組的文件。

棄用和移除

  • 字串異常已被刪除。嘗試使用它們會引發 TypeError

  • 按照 PEP 352 的要求,Exception 介面的更改仍在進行。對於 2.6,message 屬性正在棄用,轉而使用 args 屬性。

  • (3.0 警告模式)Python 3.0 將重新組織標準庫,移除許多過時的模組並重命名其他模組。在 3.0 警告模式下執行的 Python 2.6 在匯入這些模組時會發出警告。

    已棄用的模組列表為:audiodev, bgenlocations, buildtools, bundlebuilder, Canvas, compiler, dircache, dl, fpformat, gensuitemodule, ihooks, imageop, imgfile, linuxaudiodev, mhlib, mimetools, multifile, new, pure, statvfs, sunaudiodev, test.testalltoaiff

  • gopherlib 模組已被刪除。

  • MimeWriter 模組和 mimify 模組已棄用;請改用 email 包。

  • md5 模組已棄用;請改用 hashlib 模組。

  • posixfile 模組已棄用;fcntl.lockf() 提供了更好的鎖定。

  • popen2 模組已棄用;請改用 subprocess 模組。

  • rgbimg 模組已被刪除。

  • sets 模組已棄用;最好使用內建的 setfrozenset 型別。

  • sha 模組已棄用;請改用 hashlib 模組。

構建和 C API 更改

Python 的構建過程和 C API 的更改包括

  • Python 現在必須使用 C89 編譯器編譯(經過 19 年!)。這意味著 Python 原始碼樹已放棄其自己的 memmove()strerror() 實現,這些實現在 C89 標準庫中。

  • Python 2.6 可以使用 Microsoft Visual Studio 2008(版本 9.0)構建,這是新的預設編譯器。有關構建檔案,請參見 PCbuild 目錄。(由 Christian Heimes 實現。)

  • 在 Mac OS X 上,Python 2.6 可以編譯為 4 向通用構建。configure 指令碼可以帶一個 --with-universal-archs=[32-bit|64-bit|all] 開關,控制二進位制檔案是針對 32 位架構(x86、PowerPC)、64 位架構(x86-64 和 PPC-64)還是兩者都構建。(由 Ronald Oussoren 貢獻。)

  • Python 2.6.6 中新增了一個函式 PySys_SetArgvEx(),它設定 sys.argv 的值,並且可以根據 updatepath 引數的值,選擇性地更新 sys.path 以包含由 sys.argv[0] 命名的指令碼所在的目錄。

    新增此函式是為了彌補嵌入 Python 的應用程式的一個安全漏洞。舊函式 PySys_SetArgv() 總是會更新 sys.path,有時會添加當前目錄。這意味著,如果您在受他人控制的目錄中執行嵌入 Python 的應用程式,攻擊者可以在該目錄中放置一個特洛伊木馬模組(例如,一個名為 os.py 的檔案),然後您的應用程式將匯入並執行該模組。

    如果您維護一個嵌入 Python 的 C/C++ 應用程式,請檢查您是否正在呼叫 PySys_SetArgv(),並仔細考慮應用程式是否應該使用 updatepath 設定為 false 的 PySys_SetArgvEx()。請注意,使用此函式將破壞與 Python 2.6.5 及更早版本的相容性;如果您必須繼續使用早期版本,您可以保留對 PySys_SetArgv() 的呼叫不變,然後呼叫 PyRun_SimpleString("sys.path.pop(0)\n") 以丟棄第一個 sys.path 元件。

    安全問題報告為 CVE 2008-5983;在 gh-50003 中討論,並由 Antoine Pitrou 修復。

  • BerkeleyDB 模組現在有一個 C API 物件,可作為 bsddb.db.api 使用。其他希望將 bsddb 模組用於自身目的的 C 擴充套件可以使用此物件。(由 Duncan Grisby 貢獻。)

  • 新的緩衝區介面,之前在 PEP 3118 部分中描述過,添加了 PyObject_GetBuffer()PyBuffer_Release(),以及其他一些函式。

  • Python 對 C stdio 庫的使用現在是執行緒安全的,或者至少與底層庫一樣執行緒安全。如果一個執行緒關閉檔案物件而另一個執行緒正在讀取或寫入該物件,則會發生一個長期存在的潛在錯誤。在 2.6 中,檔案物件有一個引用計數,由 PyFile_IncUseCount()PyFile_DecUseCount() 函式操作。檔案物件不能關閉,除非引用計數為零。PyFile_IncUseCount() 應該在 GIL 仍然持有的時候,在使用 FILE * 指標執行 I/O 操作之前呼叫,並且 PyFile_DecUseCount() 應該在 GIL 重新獲得後立即呼叫。(由 Antoine Pitrou 和 Gregory P. Smith 貢獻。)

  • 在兩個不同執行緒中同時匯入模組不再會發生死鎖;它現在會引發 ImportError。一個新的 API 函式 PyImport_ImportModuleNoBlock() 將首先在 sys.modules 中查詢模組,然後嘗試在獲取匯入鎖後匯入它。如果匯入鎖被另一個執行緒持有,則會引發 ImportError。(由 Christian Heimes 貢獻。)

  • 有幾個函式返回有關平臺浮點支援的資訊。PyFloat_GetMax() 返回可表示的最大浮點值,而 PyFloat_GetMin() 返回最小正值。PyFloat_GetInfo() 返回一個包含 float.h 檔案中更多資訊的物件,例如 "mant_dig"(尾數中的位數)、"epsilon"(1.0 與下一個最大可表示值之間的最小差異)以及其他幾個。(由 Christian Heimes 貢獻;bpo-1534。)

  • 使用 PyComplex_AsCComplex() 的 C 函式和方法現在將接受具有 __complex__() 方法的引數。特別是,cmath 模組中的函式現在將接受具有此方法的物件。這是 Python 3.0 更改的回溯。(由 Mark Dickinson 貢獻;bpo-1675423。)

  • Python 的 C API 現在包含兩個用於不區分大小寫字串比較的函式:PyOS_stricmp(char*, char*)PyOS_strnicmp(char*, char*, Py_ssize_t)。(由 Christian Heimes 貢獻;bpo-1635。)

  • 許多 C 擴充套件在 init* 函式中定義了自己的小宏,用於將整數和字串新增到模組的字典中。Python 2.6 最終定義了用於向模組新增值的標準宏:PyModule_AddStringMacroPyModule_AddIntMacro()。(由 Christian Heimes 貢獻。)

  • 在 3.0 和 2.6 中,一些宏被重新命名,以更清楚地表明它們是宏,而不是函式。Py_Size() 變為 Py_SIZE()Py_Type() 變為 Py_TYPE()Py_Refcnt() 變為 Py_REFCNT()。混合大小寫宏在 Python 2.6 中仍然可用,以實現向後相容。(bpo-1629

  • 在除錯版本的 Python 上執行時,Distutils 現在將其構建的 C 擴充套件放置在不同的目錄中。(由 Collin Winter 貢獻;bpo-1530959。)

  • 幾個基本資料型別,例如整數和字串,維護內部可重用物件的空閒列表。這些空閒列表的資料結構現在遵循命名約定:變數始終命名為 free_list,計數器始終命名為 numfree,並且始終定義宏 Py<typename>_MAXFREELIST

  • 一個新的 Makefile 目標,“make patchcheck”,準備 Python 原始碼樹以製作補丁:它修復所有修改過的 .py 檔案中的尾隨空格,檢查文件是否已更改,並報告 Misc/ACKSMisc/NEWS 檔案是否已更新。(由 Brett Cannon 貢獻。)

    另一個新目標,“make profile-opt”,使用 GCC 的配置檔案引導最佳化編譯 Python 二進位制檔案。它透過啟用分析編譯 Python,執行測試套件以獲取一組分析結果,然後使用這些結果進行最佳化編譯。(由 Gregory P. Smith 貢獻。)

特定於埠的更改:Windows

  • 已停止對 Windows 95、98、ME 和 NT4 的支援。Python 2.6 要求至少是 Windows 2000 SP4。

  • Windows 上的新預設編譯器是 Visual Studio 2008(版本 9.0)。Visual Studio 2003(版本 7.1)和 2005(版本 8.0)的構建目錄已移至 PC/ 目錄。新的 PCbuild 目錄支援 X64 的交叉編譯、除錯構建和配置檔案引導最佳化 (PGO)。PGO 構建比普通構建大約快 10%。(由 Christian Heimes 貢獻,並得到 Amaury Forgeot d’Arc 和 Martin von Löwis 的幫助。)

  • msvcrt 模組現在支援控制檯 I/O API 的正常和寬字元變體。getwch() 函式讀取一個按鍵並返回一個 Unicode 值,getwche() 函式也一樣。putwch() 函式接受一個 Unicode 字元並將其寫入控制檯。(由 Christian Heimes 貢獻。)

  • os.path.expandvars() 現在將展開“%var%”形式的環境變數,並將“~user”展開為使用者的主目錄路徑。(由 Josiah Carlson 貢獻;bpo-957650。)

  • socket 模組的套接字物件現在有一個 ioctl() 方法,它提供了 WSAIoctl() 系統介面的有限介面。

  • _winreg 模組現在有一個函式 ExpandEnvironmentStrings(),它在輸入字串中展開環境變數引用,例如 %NAME%。此模組提供的控制代碼物件現在支援上下文協議,因此它們可以在 with 語句中使用。(由 Christian Heimes 貢獻。)

    _winreg 還更好地支援 x64 系統,公開了 DisableReflectionKey()EnableReflectionKey()QueryReflectionKey() 函式,這些函式可以啟用和停用在 64 位系統上執行的 32 位程序的登錄檔反射。( bpo-1753245 )

  • msilib 模組的 Record 物件增加了 GetInteger()GetString() 方法,這些方法以整數或字串形式返回欄位值。(由 Floris Bruynooghe 貢獻;bpo-2125。)

特定於埠的更改:Mac OS X

  • 在編譯 Python 的框架構建時,您現在可以透過向 configure 指令碼提供 --with-framework-name= 選項來指定要使用的框架名稱。

  • macfs 模組已被移除。這反過來要求移除 macostools.touched() 函式,因為它依賴於 macfs 模組。( bpo-1490190 )

  • 許多其他 Mac OS 模組已被棄用,並將在 Python 3.0 中移除:_builtinSuitesaepackaetoolsaetypesapplesingleappletrawmainappletrunnerargvemulatorAudio_macautoGILCarboncfmfileCodeWarriorColorPickerEasyDialogsExplorerFinderFrameWorkfindertoolsicicglueicopenmacerrorsMacOSmacfsmacostoolsmacresourceMiniAEFrameNavNetscapeOSATerminologypimpPixMapWrapperStdSuitesSystemEventsTerminalterminalcommand

特定於埠的更改:IRIX

一些舊的 IRIX 特定模組已被棄用,並將在 Python 3.0 中移除:alALcdcddbcdplayerCLclDEVICEERRNOFILEFLflflpfmGETGLWSGLglINIOCTLjpegpanelparserreadcdSVsvtorgbvideoreaderWAIT

移植到 Python 2.6

本節列出以前描述的更改以及可能需要更改您的程式碼的其他錯誤修復

  • 不應可雜湊的類應在其定義中設定 __hash__ = None 以表明此事實。

  • 字串異常已被刪除。嘗試使用它們會引發 TypeError

  • collections.deque__init__() 方法現在在從可迭代物件新增元素之前清除 deque 的任何現有內容。此更改使行為與 list.__init__() 匹配。

  • object.__init__() 以前接受任意引數和關鍵字引數,並忽略它們。在 Python 2.6 中,這不再允許,並將導致 TypeError。這將影響最終呼叫 object 上的相應方法(可能透過使用 super())的 __init__() 方法。請參閱 bpo-1683368 進行討論。

  • 當傳入字串時,Decimal 建構函式現在接受開頭和結尾的空白字元。以前它會引發 InvalidOperation 異常。另一方面,Context 物件的 create_decimal() 方法現在明確禁止額外的空白字元,引發 ConversionSyntax 異常。

  • 由於實現上的意外,如果您將檔案路徑傳遞給內建的 __import__() 函式,它實際上會匯入指定的檔案。然而,這從未打算起作用,並且實現現在明確檢查這種情況並引發 ImportError

  • C API:PyImport_Import()PyImport_ImportModule() 函式現在預設為絕對匯入,而不是相對匯入。這將影響匯入其他模組的 C 擴充套件。

  • C API:不應可雜湊的擴充套件資料型別應將其 tp_hash 槽定義為 PyObject_HashNotImplemented()

  • socket 模組異常 socket.error 現在繼承自 IOError。以前它不是 StandardError 的子類,但現在透過 IOError 實現了。(由 Gregory P. Smith 實現;bpo-1706815。)

  • xmlrpclib 模組不再自動將 datetime.datedatetime.time 轉換為 xmlrpclib.DateTime 型別;這種轉換語義不一定適用於所有應用程式。使用 xmlrpclib 的程式碼應轉換 datetime 例項。( bpo-1330538 )

  • (3.0-警告模式) Exception 類現在在使用切片或索引訪問時發出警告;使 Exception 表現得像一個元組正在逐步淘汰。

  • (3.0-警告模式) 兩個字典或兩個未實現比較方法的物件之間的不相等比較會被報告為警告。dict1 == dict2 仍然有效,但 dict1 < dict2 正在逐步淘汰。

    單元格之間的比較(Python 作用域規則的實現細節)也會導致警告,因為在 3.0 中完全禁止此類比較。

適用於嵌入 Python 的應用程式

  • PySys_SetArgvEx() 函式在 Python 2.6.6 中新增,允許應用程式在使用現有 PySys_SetArgv() 函式時關閉一個安全漏洞。檢查您是否正在呼叫 PySys_SetArgv() 並仔細考慮應用程式是否應使用 updatepath 設定為 false 的 PySys_SetArgvEx()

致謝

作者要感謝以下人員為本文的各種草稿提供了建議、更正和幫助:Georg Brandl、Steve Brown、Nick Coghlan、Ralph Corderoy、Jim Jewett、Kent Johnson、Chris Lambacher、Martin Michlmayr、Antoine Pitrou、Brian Warner。