Python 3.9 beta2 版本發佈了,看看這 7 個新的 PEP 都是什麼?

原做:Jake Edge python

譯者:豌豆花下貓@Python貓程序員

英文:https://lwn.net/Articles/819853/數據庫

隨着 Python 3.9.0b1 的發佈,即開發週期中計劃的四個 beta 版本的首個,Python 3.9 的功能已是完善了。在 10 月發佈最終版本以前,還會有許多測試和穩定性方面的工做要作。ide

(譯註:beta1 版本發佈於 5 月 18 日,做者文章寫於 5 月 20,而到本篇譯文發佈時,beta2 恰好在今天即 6 月 9 日發佈,這是一個巧合!)函數

該發佈說明中列出了被 3.9 接受的 7 個 Python 加強提案(PEP)。咱們研究了其中的一些 PEP,看到有一些更新。如今彷佛是一個介紹 Python 3.9 帶來的一些東西的好時機。性能

一、字符串操做

有時最簡單(代表上的)的事情最困難,或者至少會引發巨大的討論。其中大部分的爭議是關於命名(還能是什麼?),可是給標準字符串對象添加函數,來刪除前綴和後綴,這種想法是毫無爭議的。測試

是否能夠將那些詞綴(前綴和後綴的統稱)指定爲序列,以便在一次調用中處理多個詞綴,這一點尚不明確,最後它被從提案中刪除了,等待着其餘人再次推進更改。ui

在 3 月底,Dennis Sweeney 在 python-dev 郵件列表上請求核心開發者支持 PEP 616(「字符串刪除前綴和後綴的方法」)。他指出了自 2019 年 3 月以來關於該話題的 python-ideas 討論。埃裏克·史密斯(Eric V. Smith)贊成支持該 PEP,這促使 Sweeney 發佈並啓動了討論。編碼

在最第一版本中,他使用 cutprefix() 和 cutsuffix() 做爲要添加給字符串對象的方法名。四種類型的 Python 對象將得到新的方法:str(Unicode 字符串),byte(二進制序列),bytearray(可變的二進制序列)和 collections.UserString(字符串對象的一種封裝)。idea

它的寫法以下:

'abcdef'.cutprefix('abc') # 返回'def'
'abcdef'.cutsuffix('ef') # 返回'abcd'

針對命名部分,出現了一大堆的建議。基本上不多有人喜歡「cut」,所以「strip」、「strim」和「remove」被提出來了,而且都得到了一些支持。

stripprefix() 以及 stripsuffix() 因爲 PEP 中指出的一種理由,至少是被部分地反對了;現有的「strip」函數使人困惑,所以應避免重用該名稱。

str.lstrip() 和 str.rstrip() 方法也用於刪除前導字符和尾隨字符,可是它們對於真正在尋找 cutprefix() 功能的程序員來講是一個困惑的來源。

*strip() 在調用時接收一個字符串參數,但會將其視爲一組字符,並從字符串開頭或結尾消除:

'abcdef'.lstrip('abc') # 返回「def」,符合預期
'abcbadefed'.lstrip('abc') # 返回'defed',徹底不符合預期

最終,removeprefix() 和 removesuffix() 彷佛佔據了上風,這正是 Sweeney 最終改爲的版本。Guido van Rossum 也支持這些名字。

埃裏克·法格倫(Eric Fahlgren)這樣搞笑地總結了命名的爭論:

我認爲若是你先寫文檔,則名稱的選擇會更容易些:

cutprefix - 刪除指定的前綴。

trimprefix - 刪除指定的前綴。

stripprefix - 刪除指定的前綴。

removeprefix - 刪除指定的前綴。廢話 :)

Sweeney 更新了 PEP,迴應了許多評論,但還增長了提議將字符串元組做爲詞綴的功能(能夠在 PEP GitHub 倉庫中看到該版本)。

可是史蒂文·達普拉諾(Steven D'Aprano)不肯定這樣作是否合理。他指出,惟一接受元組參數的字符串操做是 str.startswith() 和 str.endswith(),而它們不返回字符串(只是一個布爾值)。他懷疑添加這一種接收元組參數卻返回字符串的方法,由於不管選擇何種規則來處理元組,對於某些人來講都是「錯誤的」選擇。

例如:

這裏的困難在於,若是兩個或多個前綴都能匹配,則「剪切這些前綴中的一個」的概念是模棱兩可的。對 startwith 沒有區別:

"extraordinary".startswith(('ex', 'extra'))

由於是從左到右,從最短到最大,甚至是隨機順序匹配都爲True。可是對於 cutprefix,應該刪除哪一個前綴?

如他所說,建議的規則是使用從左到右處理元組的第一個匹配字符串,可是有些人可能想要最長的匹配或最後一個匹配;這一切都取決於使用的上下文。他建議在提交添加此類行爲以前,要給該功能更多的「浸泡時間」(譯註:即預備時間):「在添加多前綴/後綴的支持以前,咱們首先應該對簡單的狀況進行一些實際的體驗。」

伊桑·弗曼(Ethan Furman)贊成達普拉諾(D'Aprano)的意見。可是維克托·斯汀納(Victor Stinner)強烈同意元組參數的想法,只不過,他還想知道當傳入的元組有空字符串時,會怎麼處理。根據 PEP 提議,在處理元組時遇到空字符串(實際上能夠匹配任何內容)只會返回原始字符串,這會致使使人驚訝的結果:

cutsuffix("Hello World", ("", " World"))    # 返回 "Hello World"
cutsuffix("Hello World", (" World", ""))    # 返回 "Hello"

這個例子不太明顯;詞綴不必定是硬編碼的,所以空字符串可能會溜進意想不到的位置。Stinner 建議若是遇到空字符串,則拋出 ValueError,相似於 str.split()。可是 Sweeney 決定徹底刪除元組參數功能,以便「容許對此有更強看法的人在另外的 PEP 中提出並捍衛一系列的語義」。他在 3 月 28 日發佈了該 PEP 的最新版本。

4 月 9 日,Sweeney 發起了一個指導委員會 issue,請求對其 PEP 進行評審。4 月 20 日,Stinner 表明委員會接受了該提案。

這是一個很小的更改,但值得花時間確保它具備長期適用的接口(和語義)。咱們將在 Python 3.9 中看到 removeprefix() 和removesuffix()。

二、新解析器

並不使人感到驚訝的是,指導委員會已經接受了咱們在 4 月中旬介紹過的 CPython 新解析器。PEP 617(「CPython 新的 PEG 解析器」)由 Python 創始人即前仁慈的獨裁者(BDFL) Guido van Rossum 以及 Pablo Galindo Salgado 和 Lysandros Nikolaou 共同提出。

它已經運行良好,而且在現有解析器的速度和內存使用方面提高了 10% 之內的性能。因爲解析器是基於解析表達語法(PEG),所以也將簡化語言規範。CPython 現有的 LL(1) 解析器存在諸多缺點和一些 hack,新的解析器將會消除掉。

這一更改成 Python 超越 LL(1) 語法鋪平了道路,儘管現有語言並不徹底是 LL(1)。這一更改不會太快,由於計劃是在 Python 3.9 的命令行中提供開關,保持現有解析器可用。

可是 Python 3.10 將刪除現有的解析器,這可能會致使語言變動。若是作了那些更改,那麼,其它的 Python 實現(例如 PyPy 和 MicroPython)就須要切換解析器的 LL(1) 實現,以便跟上語言規範的要求。這可能會使核心開發者暫停進行此類更改。

三、更多內容

咱們在三月初查看了 PEP 615(「在標準庫中支持 IANA 時區數據庫」)。它將在標準庫中添加一個zoneinfo 模塊,該模塊將有助於從 IANA 時區數據庫中(也稱爲「Olson數據庫」)獲取時區信息,以填充時區對象。在撰寫本文時,它看起來很順利。

在 3 月底,Paul Ganssle 請求就該 PEP 做出決議。他認爲在一個有趣的時間範圍內接受它,可能會頗有趣:

... 我但願(出於異想天開的緣由)在 4 月 5 日(星期日)UTC 時間 02:00-04:00 或 13:00-17:30 之間接受它,由於這些時間表明着地球上某些地方的不明確時間(主要在澳大利亞)。還有另外一個時機,那就是在 4 月 19 日星期日 UTC 01:00-03:00 之間,這段時間在西撒哈拉是不明確的。

他意識到這可能難以實現,它固然不是優先考慮的事。指導委員會沒有錯過第二個時間窗太多;Barry Warsaw 於 4 月 20 日宣佈接受該 PEP。

Python 如今將具備一種機制來訪問系統的時區數據庫,以建立和處理時區。另外,Python 軟件包索引(PyPI)中有一個 tzdata 模塊,它爲缺乏 IANA 數據的系統提供這些數據;它將由 Python 核心開發者維護。

PEP 593(「靈活的函數和變量註釋」)添加了一種將上下文特定的(context-specific)元數據與函數和變量關聯的方法。實際上,type hint 註解已擠出了不少年前在 Python 3.0 中實現的 PEP 3107(「函數註釋」)中設想的其它用例。PEP 593 使用註解的(Annotated)類型提示爲這些用例建立了一種新的機制。

PEP 585(「標準集合中的類型提示泛型」)提供了另外一種清除方法。它將容許刪除在 typing 模塊中維護的一組並行的類型別名,以支持泛型。例如,type.List 類型將再也不須要支持諸如「dict[str,list[int]]」之類的註解(例如,一個帶有字符串鍵和整數列表的值的字典)。

字典「加法」的聯合操做也會是 Python 3.9 的一部分。它曾不時引發爭議,可是 2 月中旬,PEP 584(「給字典添加聯合操做符」)被 Van Rossum 推薦採納。指導委員會迅速贊成了,該特性於 2 月 24 日合入。

最後一個 PEP 是 PEP 602(「Python 的年度發佈週期」)。如提案所書,它將發佈節奏從每 18 個月更改成每一年一次。可是,開發和發佈週期是重疊的,所以整個功能開發須要 12 個月的時間。當第一個 Python 3.9 beta 版本發佈時(即如今),Python 3.10 的功能開發就開始了。請繼續關注來年的下一輪 PEP。

相關文章
相關標籤/搜索