PEP 集錦
PEP 集錦
在 Python10 會議 的開發者日開始時,我做了一個主題演講,最後是以我稱之為“PEP 集錦”的內容結束。這是對 所有開放的 PEP 的簡要概述,我對每個 PEP 都給出了我個人且主觀的意見。後來,我意識到這可能對其他開發者也有用。我沒有在會議上做筆記,所以下面是我在 2002 年 3 月 7 日的兩個小時內從頭開始建立的一組不同的評論。我打算偶爾用新的評論和新的 PEP 更新此內容。
--Guido van Rossum
PEP 42 - 小型特性請求 - Hylton
坦白地說,這主要是“錦上添花”想法的垃圾場,這些想法沒有足夠的優先順序來實施。似乎沒有人會瀏覽它並找到一個好主意,為之編寫程式碼並提交補丁。所以實際上,一個被移到 PEP 42 的想法比一個被直接拒絕的想法更糟糕——它處於一個殭屍區,既不能昇天堂也不能下地獄。我們如何改變這種情況?
PEP 206 - 2.0 自帶電池 - Zadka
這是一個好主意。但 PythonLabs 沒有精力推進它,原作者也沒有。我們如何使之成為社群努力?
PEP 209 - 新增多維陣列 - Barrett, Oliphant
2002 年 3 月 28 日: 我之前的評論是基於幾個誤解。(例如,新 Numeric 中的切片與舊版本中的行為相同,並且不會像我錯誤地認為的那樣進行復制。)引用 Perry Greenfield 的話:
[...] 新版本越來越向後相容。事實上,仍然存在的主要差異是
- 當標量與陣列組合時,強制轉換規則存在差異。在科學 Python BoF 上,人們一致認為這種改變是一件好事。
- 型別由型別物件而不是單個字元程式碼表示。我們已經實現了這一點,使其向後相容,因此很少有舊的 Python 程式碼會因此而被破壞。
- Python 2.2 之前的版本沒有陣列屬性(即 shape、flat、real 和 imag)(我們使用屬性功能來支援 2.2 及更高版本;因此它只與舊版本的 Python 中的 Numeric 不相容)
還有更多次要差異,但這些是 Python 級別的主要向後相容性問題。其中兩個對於大多數使用 Python 2.2 或更高版本的使用者來說應該不是問題。它確實有一些重要的增強功能,但這些不是相容性問題。它被接受的最大問題可能是
- 不相容的 C API。我們可以提供工具來簡化 C 程式碼的適配,但我們無法使其自動化。
- 缺乏庫。我們正在開始記錄 API,提供如何新增 C 程式碼的示例,並新增一些標準庫。在有足夠的庫支援(包括繪圖)之前,將會有足夠的功能關鍵質量讓人們開始切換(天文學除外,這些將由我們使用 numarray 的庫驅動)
- 小陣列的效能較慢。由於其中更多的是用 Python 編寫的,因此對於較小的陣列來說,它的速度慢了一個數量級(但對於較大的陣列(> 1MB)來說,它的速度同樣快或更快)。最佳化已在我們的計劃中,但要等到我們完成庫並完成安全問題(即將完成)後才會進行。
- 由於 1) 和 2),目前使用它的人不多(有些人很忙,覺得 Numeric 適合他們的目的;僅僅可用性並不能讓他們嘗試並給出他們的意見。)
[關於整合到 Python 核心中]
好吧,這仍然是我們的目標,我們正在為此努力(我們甚至開始考慮將文件轉換為 Python 標準)。有一份手冊草稿可用。我估計可能需要一年時間,社群才會開始大量切換使用它(假設我們成功地讓他們這樣做)。
另一方面,我不認為該時間表應該必然成為它何時(或是否)被核心接受的驅動因素。它可以在此之前(它們具有不同的名稱並且可以共存)或之後很久被核心接受。我認為這個決定應該在稍微不同的基礎上做出。
Paul Dubois 傳送電子郵件支援 Perry 的訊息,宣佈他很快將成為一個特定應用程式的 Numarray 使用者。Paul 還提到 C API 是唯一令人討厭的問題。他不認為小陣列的效能問題是多大的問題。
基於此反饋,我預計此 PEP 將緩慢但穩定地向前發展。我希望作者最終會向我提供一個補丁集,將其程式碼庫合併到 Python CVS 樹中。這是否適用於 Python 2.3 或更高版本,我無法判斷。
PEP 215 - 字串插值 - Yee
我預見這裡的爭論永遠不會得出明確的結論。有些人認為這是 YAGNI(你不會需要它)的明顯案例,而另一些人則認為這是初學者最重要的缺失特性。我不知道哪一方是對的。即使它是一個需要的功能,語法也是有問題的:第一個 $ 在
print $"The area of a $x by $y rectangle is $z"
非常有問題,但我看到的所有替代方案(例如,i"...")看起來都不太好。我們不能總是開啟文字中的字串插值,因為這會破壞現有程式碼。也許“from __future__ import interpolation”會在字串文字中啟用插值?(僅在文字中!)
還有一個問題是是否允許任意表達式,例如
print "The area is ${x*y}"
PEP 216 - 文件字串格式 - Zadka
這幾乎沒有內容。也許應該撤回?還有幾個其他處理文件字串的 PEP,特別是 256-258,我更喜歡這些。
PEP 228 - 重構 Python 的數值模型 - Zadka, van Rossum
這太過於不切實際了。有太多未解決的問題,而且許多問題甚至沒有在 PEP 中提及。我認為應該拒絕;也許如果未來對此有興趣,可以建立一個工作組或 SIG 來更深入地探索這個主題。
PEP 237 - 統一長整數和整數 - Zadka, van Rossum
這個已經被接受了,我們應該在 Python 2.3 中實現 B1 階段。我還需要多說嗎?
PEP 239 - 向 Python 新增有理型別 - Zadka
像 228 一樣,我認為這不是一個現實的 PEP,它只是一堆未解決的問題。有理型別似乎會帶來更多問題而不是解決問題。
也許,僅僅是也許,可以在擴充套件模組中用 C 實現一個高效的有理型別(當然使用 Python 長整數)。但這只是辛勤工作的問題,而且似乎沒有人感興趣。同時,如果您需要有理數,那麼有大量純 Python 實現可用(包括 Demo/classes/Rat.py)。
PEP 240 - 向 Python 新增有理文字 - Zadka
鑑於我對 239 的評論,我建議拒絕此項。
PEP 242 - 數值型別 - Dubois
除了作者之外,似乎沒有人有興趣繼續研究這個。我個人認為這個想法並不是特別 Pythonic——趨勢是減少數值型別,而不是增加(參見 PEP 237)。我相信作者已經表示,最好撤回 PEP。
PEP 243 - 模組儲存庫上傳機制 - Reifschneider
當然,很好,但這應該是一個社群共同努力的專案。或許 Kapil 的模組倉庫專案(Gideon,/usr/local/WWW/ftp.python.org/pub/www.python.org/sigs/catalog-sig)會給它帶來新的活力?
我認為這裡的問題不僅僅是軟體本身,而是 (a) 建立一個能夠承受整個社群訪問的伺服器(或一組副本),以及 (b) 動員社群將他們所有的程式碼提交到倉庫中。
另一個問題是審查。我認為 CPAN 也沒有完全解決這個問題(考慮到我聽到的關於軟體包無法正常工作的抱怨)。你如何知道哪些貢獻是好的?計算下載量?一個“為這個軟體包投票”的表格?
原始作者計劃做什麼?
PEP 245 - Python 介面語法 - Pelletier
Jim Fulton 說這個 PEP 太過倉促。我同意。它引入了一個新的關鍵字 'interface',我還不確信這是必要的。另一方面,目前在 Zope 中實現介面的方式也很醜陋,所以可能確實需要一些改進。我認為在未來某個時候,當我們有更多使用介面的經驗(尤其是在 Zope 3 中)時,我們會回到這個 PEP,看看我們能用上多少。也許應該有一個特殊的“凍結”狀態,意味著不拒絕,但近期也不考慮?但與“空中樓閣”不同,這個 PEP 至少有很多具體的建議,並研究了其後果。
PEP 246 - 物件適配 - Evans
直到 Alex Martelli 向我解釋之後,我才理解這個 PEP 是關於什麼的。我認為它類似於 Zope 3 中的一個操作,它查詢給定物件的介面卡,該介面卡實現了給定的介面。如果物件本身實現了該介面,則返回物件本身;否則,會系統地搜尋已註冊的介面卡表,以找到最合適的介面卡。
但這就是我對此主題的全部瞭解,我認為在找到一種描述介面的標準方式之前,它應該保持為一個好主意。所以我認為它將具有“凍結”狀態(見上文),至少與 PEP 245 一樣長的時間。
我不得不承認,我從未完整閱讀過整個 PEP,當然也沒有嘗試閱讀和理解規範或示例實現,所以也許我仍然理解有偏差。
PEP 254 - 使類更像型別 - van Rossum
這個 PEP 旨在描述對經典類實現的更改,使其更接近新式類。我還沒有開始這項工作,而且我認為也許沒有必要——經典類實現可以保持原樣,直到它在 Python 3000 中被簡單地刪除。在某個時候,當我們相信大多數使用者都在使用新式類時,我們應該為使用舊式類新增警告。這個 PEP 可以用來描述這些警告的時間框架。但在此之前,我們應該首先確保整個標準庫(以及演示和工具)都使用新式類。這甚至不會在 Python 2.3 中發生。此外,這可能會破壞使用者程式碼,這些程式碼繼承了特定的標準類,例如,如果使用者定義了一個依賴於強制轉換的子類,而新式類不支援強制轉換。
PEP 256 - 文件字串處理系統框架 - Goodger
PEP 257 - 文件字串約定 - Goodger, van Rossum
PEP 258 - DPS 通用實現細節 - Goodger
我將一起討論這些。我相信 David Goodger 正在做很好的工作,我仍然在 doc-sig 中看到他頻繁的帖子。但我根本沒有關注這項工作。由於這不影響語言,只是一個約定,我並不特別關心這個。
PEP 262 - 已安裝 Python 包的資料庫 - Kuchling
我認為這是一個 distutils 的“空中樓閣”專案?也許有人應該實現它;我對此沒有意見,但我自己並沒有特別感到需要。
PEP 263 - 定義 Python 原始碼編碼 - Lemburg
這個非常接近被提交了。Martin 和 Marc-Andre 正在討論實現方案。當他們準備好時,我想我會直接批准它。一位外部專家 Stephen Turnbull 提出了嚴重反對意見,他希望我們用 UTF-8 定義純語言,並將編碼實現為特定於站點的(?)鉤子。但沒有人同意他的觀點,我親自回應說,我認為最好按照 MAL 的方式去做。
PEP 265 - 按值排序字典 - Griffin
這是一個對提議者來說非常重要的小想法,但在我看來,它試圖解決一個可以透過其他方式更好地解決的問題,例如,透過教新手正確的演算法/習慣用法。我注意到該 PEP 使用了馬虎的語言,例如,它談論“排序字典”,而字典本身永遠不會被排序——該 PEP 僅提出返回按排序順序排列的專案或鍵的方法。
該 PEP 也缺乏明確性:它提出了一系列替代方案,我猜我應該從中選擇我最喜歡的一個。這又讓我成了壞人。:-)
最後,提議的“reversed=<bool>”可選引數似乎完全是特定於應用程式的。
我想拒絕這個,因為它沒有以足夠通用的方式解決足夠通用的問題,它只是讓字典 API 變得混亂。我寧願新增 dict.popitem(key)。
PEP 266 - 最佳化全域性變數/屬性訪問 - Montanaro
PEP 267 - 最佳化對模組名稱空間的訪問 - Hylton
PEP 280 - 最佳化對全域性變數的訪問 - van Rossum
這三個應該一起考慮;最多可以實現其中一個(或者可能是混合的)。我希望最終實現其中一個,因為我認為它可能會帶來很大的效能提升:不僅避免了全域性變數和內建函式的字典查詢,而且還可以在解析器中識別某些內建函式,並生成知道內建函式作用的程式碼,例如 len(x) 的操作碼和“for i in range(x, y, z)”的特殊程式碼。
我認為 Montanaro 的提議過於複雜。我喜歡 Hylton 的版本和我自己的版本一樣;他的版本有一些可選功能(例如,支援表示“模組.屬性”的全域性屬性),我認為不值得增加額外的複雜性。
在上次 PythonLabs 會議上,我們決定首先做一些不那麼雄心勃勃的事情,看看在 2.3 之前是否有時間在完成這些之後做更多的事情。不那麼雄心勃勃的事情是重構編譯器,使用更合適的抽象語法樹,並引入顯式的多遍處理。我預測僅此一項在 2.3 beta1(7 月 17 日)之前剩餘的時間裡就已經很難做到了。
PEP 268 - 擴充套件 HTTP 功能和 WebDAV - Stein
我完全支援這個,但這是庫開發工作,我不會去做。
似乎作者已經放棄了,而且沒有人接手。在 sandbox/Lib 目錄(奇怪的名稱)中有一個 2001 年 9 月的實際原型;也許我們應該催促作者完成這項工作,或者問問他在等什麼。
PEP 269 - Python 的 Pgen 模組 - Riehl
我知道 Martin von Loewis 不喜歡這個(因為它缺乏通用性,例如,除了定義保留字集之外,沒有辦法更改詞法分析器),但我認為它對於那些嘗試使用類似 Python 的語言(例如,新增新關鍵字和語法的 Python 預處理器)的人來說可能有些用處。由於 pgen 與 Python 發行版緊密繫結,因此將使 pgen 可供 Python 程式設計師使用的擴充套件也應該包含在 Python 發行版中是有意義的。
因此,我們應該問問作者是否計劃實現它。如果沒有,那麼它可能會因缺乏興趣而被放棄。
PEP 270 - 列表物件的 uniq 方法 - Petrone
與 PEP 265 的故事相同。正如關於這個主題的激烈的食譜條目所證明的那樣,要完全通用地做到這一點要比看起來困難得多。該 PEP 是未完成的:它甚至沒有指定所需的語義!而且為什麼沒有包含作者的實現,如果它只有 20 行?
我建議拒絕這個,以節省作者的工作(他仍然應該公開他的實現)。
PEP 273 - 從 Zip 存檔匯入模組 - Ahlstrom
我喜歡這個概念。我沒有詳細研究該 PEP 或提議的實現,所以我不知道它是否總是做正確的事情。我希望它能進入 2.3。
PEP 274 - 字典推導式 - Warsaw
如果我們採用字典推導式,那麼這個 PEP 說明了所有需要說明的內容。但我甚至不想在 Python 2.3 中考慮這個問題;我認為它是一個太小的特性。
如果有補丁形式的工作實現,這將更容易採用。
有時,如果可以使用衛生宏或其他型別的預處理器或其他東西來定義類似這樣的東西,並從模組中匯入,而不是需要在解析器、位元組碼編譯器和虛擬機器中進行大量破解,那就太好了。
PEP 275 - 根據多個值切換 - Lemburg
我仍然不相信我們需要一個 switch 語句,並且提議的語法存在問題:例如,為什麼只允許常量?為什麼不允許範圍?此外,它提出了許多不同的替代方案,而沒有選擇一個。
然而,該 PEP 提出的第一個替代方案並沒有新增任何新語法,而只是建議解析器識別某種常見的模式併為其生成更好的程式碼。我完全支援這一點,前提是能夠證明生成的程式碼要麼速度明顯更快,要麼體積明顯更小,或者兩者兼而有之。在上面關於 PEP 266、267、280 的評論中提出的編譯器重構之後,這個專案可能會容易得多。
PEP 276 - int 的簡單迭代器 - Althoff
我犯了一個錯誤,告訴作者我覺得這很醜陋。不管用什麼詞,我確實認為這與 Pythonic 相悖。對我來說
for i in 12: print i
看起來就不對勁。也許
for i in len(L): print i, L[i]
很有吸引力,但不知何故,我只是認為這不是正確的解決方案。
PEP 277 - Windows NT 的 Unicode 檔名支援 - Hodgson
我不知道這個的狀態,但我相信這已經實現或者至少接近實現了?這在德國人中存在爭議嗎?
PEP 278 - 通用換行符支援 - Jansen
我給 Jack 發了一堆唱反調的問題。這個問題是真實存在的,我希望看到它得到解決,但我擔心這有點太像駭客行為了。這是列表
- source() 呼叫到底是什麼?
- 為什麼不支援為輸出檔案設定分隔符?
- 't' 模式與在 Windows 上使用此模式來顯式呼叫預設文字轉換模式相沖突。
- 為什麼不能將 't' 與 '+' 一起使用?據我所知,Windows 上的文字模式支援 '+'。
- 這如何與 xreadlines 互動?與 "for line in file" 互動?
- 為什麼選擇預設關閉的編譯時選項?那是在自找麻煩;開啟它的人會編寫使用 't' 模式的程式碼,然後發現它是不可移植的。
- 你說 import 使用 't' 模式。從字串解析原始碼怎麼辦?Unicode 字串怎麼辦?
- 我想我需要對你關於鎖的評論有更多的澄清。如果可以濫用實現來建立核心轉儲,我不會支援它。
PEP 279 - 增強的生成器 - Hettinger
2002 年 3 月 28 日: 作者採納了我的建議,刪除了可重啟迭代器的想法,我在之前的評論中稱之為邪惡的。這是我目前的評論
- 新的內建函式:indexed()
我喜歡以某種方式並行迭代序列及其索引集的想法。將其作為內建函式很好。
我不喜歡“indexed”這個名字;形容詞不適合作為函式名。也許 iterindexed() 更好?
我不喜歡 start 和 stop 引數。如果我看到類似這樣的程式碼:
for i, j in iterindexed("abcdefghij", 5, 10): print i, j
我會期望它列印:5 f 6 g 7 h 8 i 9 j
而 PEP 中的規範會列印:5 a 6 b 7 c 8 d 9 e
非常令人困惑。我建議移除 start/stop 引數,或者更改規範為:
def iterindexed(sequence, start=0, stop=None): i = start while stop is None or i < stop: try: item = sequence[i] except IndexError: break yield (i, item) i += 1
這將有效性限制為僅限序列(而不是所有可迭代集合),但優點是使 iterindexed(x, i, j) 迭代 x[i:j] 時,報告的索引序列是 range(i, j) -- 否則就不那麼容易實現了。
簡化版本仍然很有吸引力,因為它允許傳入任意迭代器:
def iterindexed(collection): i = 0 it = iter(collection) while 1: yield (i, it.next()) i += 1
- 生成器推導式
我認為這不值得麻煩。我預計將其破解到程式碼生成器中會花費大量精力:它必須建立一個單獨的程式碼物件才能成為生成器。列表推導式是內聯的,所以我預計生成器推導式程式碼生成器無法與列表推導式程式碼生成器共享太多。而且這對於不常見且容易透過編寫一個 2 行輔助函式來完成的事情來說。換句話說,投資回報率不夠高。
- 生成器異常傳遞
這是 PEP 似乎最薄弱的地方。沒有真正的動機(“這是一個真正的缺陷”不算數 :-)。沒有關於應該如何實現的提示。示例中生成器主體中有一個“return log”語句,這在當前是非法的,我無法弄清楚這個值會返回到哪裡。這個例子看起來不需要生成器,如果需要,可以透過設定一個全域性“請停止”標誌並再次呼叫 next() 來輕鬆停止生成器。(如果你不喜歡全域性變數,可以將生成器設為一個類的方法,並將停止標誌設為一個例項變數。)
PEP 281 - 使用 range 和 xrange 的迴圈計數器迭代 Hetland
這是 PEP 212 中 irange() 的一個替代方案(該方案被拒絕了,但沒有文字解釋為什麼被拒絕)。只要我們要引入一個返回 range(0,len(sequence)) 的(惰性或其他)版本的 FOO(sequence) 符號,我認為使用 FOO==range 比其他任何東西都更令人困惑。換句話說,如果我們必須這樣做,請為其發明一個新名稱。
PEP 282 - 日誌系統 - Mick
我要求了這個,甚至還沒有看過。但我已經喜歡它了!我希望這可以在 2.3 中實現。
PEP 284 - 整數 for 迴圈 - Eppstein, Ewing
這是解決一些人覺得:
for i in range(10):
太醜陋的又一種方法。我對這個的主要抱怨是:
for 0 <= i < 10:
將索引變數放在中間,而不是緊跟在 for 關鍵字之後。而且在下限是變數的情況下,這對隨便看看的讀者來說是令人困惑的:
for i <= j < k:
看起來類似於:
for i in j, k:
但在一種情況下,迴圈計數器是 j,在另一種情況下,迴圈計數器是 i。
這個 PEP 的好處在於,它引用並評論了所有以前試圖解決這個問題的 PEP(204、212、276 和 281)。
我認為當前的解析器生成器必須被嚴重濫用才能允許以下兩個語法選項:
for <target_list> in <expression_list>
和
for <expression> <comparison> <target> <comparison> <expression>
因為 <target_list> 可以以 <expression> <comparison> 開頭。
結束語
哇!就這樣了。嗯,在被放棄的類別中還有一些 PEP 可能值得評論,但我會等到有人想重新啟動它們。我們絕對應該更清楚地區分被拒絕的和被推遲的 PEP。而且不應該有任何被拒絕的 PEP 沒有被拒絕的解釋。