Python 2.6 新特性

作者:

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

本文介紹了 Python 2.6 的新特性,該版本於 2008 年 10 月 1 日釋出。釋出計劃在 PEP 361 中描述。

Python 2.6 的主要主題是為遷移到 Python 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 添加了幾個新的內建函式,並更改了一些現有內建函式的語義。像 bin() 這樣在 3.0 中是新的函式已被簡單地新增到 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 的錯誤跟蹤器越來越感到惱火。SourceForge 的託管解決方案不允許太多自定義;例如,無法自定義問題的生命週期。

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

在釋出志願者徵集後,在 https://bugs.python.org 上設定了一個新的 Roundup 安裝。一個 Roundup 安裝可以託管多個跟蹤器,並且該伺服器現在還託管 Jython 和 Python 網站的問題跟蹤器。將來它肯定會找到其他用途。在可能的情況下,此版本的“Python 新特性”會連結到每個變更的錯誤/補丁項。

Python 錯誤跟蹤器的託管由南非斯泰倫博斯的 Upfront Systems 慷慨提供。Martin von Löwis 花費了大量精力從 SourceForge 匯入現有的錯誤和補丁;他用於此匯入操作的指令碼位於 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 編寫。在 20 世紀 80 年代和 90 年代初期,大多數文件都是打印出來以便日後學習,而不是線上檢視。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__() 方法,但 *type*、*value* 和 *traceback* 都為 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 一個值。 yield 之前的所有程式碼都將作為 __enter__() 方法執行,而 yield 的值將是該方法的返回值,它將繫結到 ‘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” 語句

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

contextlib 模組的文件。

PEP 366:從主模組進行顯式相對匯入

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

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

然後,PEP 302 樣式的匯入器可以根據需要設定 __package__runpy 模組實現了 -m 開關,現在可以執行此操作,因此相對匯入現在可以在從包內部執行的指令碼中正常工作。

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 目錄

由 Christian Heimes 編寫和實現的 PEP。

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 - 新增 multiprocessing 包

由 Jesse Noller 和 Richard Oudkerk 編寫的 PEP;由 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 - 高階字串格式化

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

PEP 3105:print 作為函式

print 語句在 Python 3.0 中變為 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 作為函式

由 Georg Brandl 編寫的 PEP。

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 中捕獲異常

由 Collin Winter 編寫和實現的 PEP。

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 屬性,該屬性儲存底層的原始物件。

    有五個具體的類實現了這個 ABC。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 - 修訂緩衝區協議

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

PEP 3119:抽象基類

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

假設你有一個特定的類,並且想知道它是否支援字典式訪問。然而,“字典式”這個詞是模糊的。它可能意味著使用 obj[1] 訪問專案有效。它是否意味著使用 obj[2] = value 設定專案有效?或者該物件將具有 keys()values()items() 方法?迭代變體(如 iterkeys())呢? copy()update()?使用 iter() 迭代物件?

Python 2.6 collections 模組包含許多不同的 ABC,這些 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 派生可能更清晰。register() 方法在你編寫可以描述現有型別或類的新 ABC 時,或者你想宣告某個第三方類實現了 ABC 時非常有用。例如,如果你定義了一個 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 無法提供有用的通用實現。

你可以將 @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 - 引入抽象基類

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

PEP 3127:整數文字支援和語法

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

Python 2.6 不會放棄對以 0 開頭表示八進位制數的支援,但它確實增加了對 “0o” 和 “0b” 的支援

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

oct() 內建函式仍然返回以 0 開頭的數字,而新的 bin() 內建函式返回數字的二進位制表示形式

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

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

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

另請參閱

PEP 3127 - 整數文字支援和語法

由 Patrick Maupin 編寫的 PEP;由 Eric Smith 向後移植到 2.6。

PEP 3129:類裝飾器

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

@foo
@bar
class A:
  pass

這等效於

class A:
  pass

A = foo(bar(A))

另請參閱

PEP 3129 - 類裝飾器

由 Collin Winter 編寫的 PEP。

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

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

最通用的 ABC 是 Number。它沒有定義任何操作,並且僅存在以允許透過執行 isinstance(obj, Number) 來檢查物件是否為數字。

ComplexNumber 的子類。複數可以進行加法、減法、乘法、除法和求冪的基本運算,你可以檢索實部和虛部並獲得數字的共軛。Python 的內建複數型別是 Complex 的實現。

Real 類進一步派生自 Complex 類,並添加了僅適用於實數的操作:floor()trunc()、舍入、取模 N 的餘數、向下取整除法以及比較。

Rational (有理數)類派生自 Real 類,具有 numerator(分子)和 denominator(分母)屬性,並且可以轉換為浮點數。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 - 數字型別層次結構

由 Jeffrey Yasskin 撰寫的 PEP。

Guile 手冊中的 Scheme 數值塔

R5RS Scheme 規範中的 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)

對於將浮點數轉換為有理數,浮點型別現在有一個 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(),如果它們的浮點引數是無窮大或非數字(NaN),則返回 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 sprint 的努力下,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 檔案。 此設定在 Python 程式中可用作 sys.dont_write_bytecode 變數,並且 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 模組現在使用可用的最高 pickle 協議,而不是限制為協議 1。(由 W. Barnes 貢獻。)

  • cgi 模組現在將從 HTTP POST 請求的查詢字串中讀取變數。這使得可以使用包含查詢字串的 URL 來進行表單操作,例如 “/cgi-bin/add.py?category=1”。(由 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() 返回複數的引數(也稱為角度)。

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

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

    修訂還改進了 cmath 模組的數值穩健性。對於所有函式,結果的實部和虛部在可能的情況下都精確到幾個最小精度單位 (ulp) 以內。有關詳細資訊,請參見 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 屬性。在某些瀏覽器中,無法透過 JavaScript 程式碼訪問或操作設定此屬性的 cookie。(由 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 引數提供 true 值來啟用插入模式。

  • 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 貢獻。)

  • 一個可選的 timeout 引數(以秒為單位指定超時時間)已新增到 ftplib.FTP 類建構函式以及 connect() 方法中。(由 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 貢獻。)

  • 一個可選的 timeout 引數(以秒為單位指定超時時間)已新增到 httplib.HTTPConnectionHTTPSConnection 類建構函式中。(由 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]) 返回可迭代物件元素的所有長度為 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 貢獻。)

  • 一個 get_data() 函式被新增到 pkgutil 模組中,該函式返回與已安裝的 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 位系統上進行 pickle 序列化,並在 64 位系統上進行反序列化,反之亦然。不幸的是,此更改還意味著 Python 2.6 的 Random 物件無法在早期版本的 Python 上正確反序列化。(由 Shawn Ligocki 貢獻;bpo-1727780。)

    新的 triangular(low, high, mode) 函式返回符合三角分佈的隨機數。返回的值在 *low* 和 *high* 之間,不包括 *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() 系統呼叫的包裝函式。將 modify() 方法新增到現有的 poll 物件;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。)

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

    還添加了 setitimer()getitimer() 函式(在它們可用的地方)。setitimer() 允許設定間隔計時器,這些計時器會在指定時間(以實際時間、消耗的程序時間或組合的程序+系統時間衡量)後向程序傳送訊號。(由 Guilherme Polo 貢獻;bpo-2240。)

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

    該模組中還添加了 LMTP 協議 (RFC 2033) 的實現。LMTP 在不管理郵件佇列的代理之間傳輸電子郵件時,用來代替 SMTP。(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-742598bpo-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 屬性為 true,如果在除錯模式下,則 debug 為 true,等等。這些屬性都是隻讀的。(由 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) tar 檔案。預設格式為 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。)

  • 用於海龜圖形的 turtle 模組由 Gregor Lingl 大大增強。該模組的新功能包括

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

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

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

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

    • 簡單支援響應諸如滑鼠和鍵盤活動之類的輸入事件,從而可以編寫簡單的遊戲。

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

    • 該模組的文件字串可以替換為已翻譯成另一種語言的新文件字串。

    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 的一部分新增,它在 C 程式碼中重新實現了 warnings 模組的一部分。)

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

  • 透過將 False 作為 *bind_and_activate* 建構函式引數傳遞,現在可以阻止 XML-RPC 的 SimpleXMLRPCServerDocXMLRPCServer 類立即開啟並繫結到它們的套接字。這可以用於在呼叫 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 程式設計之夏專案的一部分貢獻。)

  • 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):這些版本將呼叫 __index__() 方法並將結果轉換為十六進位制或八進位制,而不是呼叫 __hex__()__oct__() 方法。oct() 將使用新的 0o 表示法來表示其結果。

json 模組:JavaScript 物件表示法

新的 json 模組支援 JSON (JavaScript 物件表示法) 中 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()

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

改進的 SSL 支援

Bill Janssen 對 Python 2.6 的安全套接字層支援進行了大量改進,添加了一個新模組 ssl,該模組基於 OpenSSL 庫構建。這個新模組提供了對協商協議、使用的 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 的更改包括

  • (19 年後!)Python 現在必須使用 C89 編譯器進行編譯。這意味著 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() 函式操作。除非引用計數為零,否則無法關閉檔案物件。在使用 FILE * 指標執行 I/O 操作之前,應在仍持有 GIL 的情況下呼叫 PyFile_IncUseCount(),並在重新獲取 GIL 後立即呼叫 PyFile_DecUseCount()。(由 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 上相應方法的 __init__() 方法(可能透過使用 super())。 有關討論,請參閱 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。