看完 Python3.10 的新特性,我決定仍不更新
Python3.10 在 2021 年的 10 月 3 號發(fā)布,目前已經(jīng)過去 1 個月了,關(guān)于它的新特性相信大家已經(jīng)有所耳聞,不過我決定仍然不更新,目前我在用的版本是 Python3.8,沒有任何不爽。下面說一說我不更新的理由。
第一、相關(guān)的庫可能還未跟進(jìn)
如果你更新到了最新版本,已有的代碼能否在不修改的情況下仍然可以正常運(yùn)行?是首先要考慮的問題。
Python 的第三方庫都是基于開源志愿者的勞動,他們免費(fèi)做著非常有價值的工作,而且適配新的 Python 版本都需要時間。此外,由于升級涉及許多不同的群體,協(xié)調(diào)和發(fā)布需要更多時間。
第二、很多新特性沒使用價值
盤點(diǎn)一下 Python3.10 的那些沒什么用的新特性(個人觀點(diǎn),可以留言來噴):
1、with 可以加括號了
比如:
- with (
- CtxManager1() as example1,
- CtxManager2() as example2,
- CtxManager3() as example3,
- ):
- ...
這一點(diǎn),我基本用不到,也不清楚什么樣的情況需要這樣寫。要是有多個上下文,我就串著多寫幾個就是了,要是 example1 和 example2 有關(guān)系,我可以嵌套:
- with CtxManager1() as example1:
- with CtxManager2() as example2:
- ...
- ...
這樣寫不是層次更清晰嗎?
2、match case 就是花花腸子
Python3.10 新增了 match 和 case 軟關(guān)鍵字。什么是軟關(guān)鍵字?就是雖然是關(guān)鍵字,但是可以作為變量名,雖然如此,你肯定也不愿意讓 match 成為你的變量名了,因?yàn)檫@樣也是不會報錯的:
match match: #后一個 match 是變量名稱
- match match: #后一個 match 是變量名稱
- case case:
- <action>
3.10 的 match case 的語法如下:
- match subject:
- case <pattern_1>:
- <action_1>
- case <pattern_2>:
- <action_2>
- case <pattern_3>:
- <action_3>
- case _:
- <action_wildcard>
它的用法可多了,有些我都快看不懂了。比如先來個簡單的:
- def match_errno(errno):
- match errno:
- case 0:
- pass
- case 1:
- pass
- case 42:
- print("42!")
- case _:
- print("wildcard")
這里有個 _ 表示誰也不匹配的情況,相當(dāng)于一個默認(rèn)值,但是 _ 本來是用來表示一個后續(xù)不再使用的變量的,假如這樣調(diào)用,雖然解釋的通,總感覺怪怪的:
- >>> _ = 42
- >>> match_errno(_)
- 42!
再來個復(fù)雜一點(diǎn)的:
- def command_split(command):
- match command.split():
- case ["make"]:
- print("default make")
- case ["make", cmd]:
- print(f"make command found: {cmd}")
- case ["restart"]:
- print("restarting")
- case ["rm", *files]:
- print(f"deleting files: {files}")
- case _:
- print("didn't match")
我乍一看覺得這代碼有問題,cmd 和 files 是未定義的變量啊,卻可以用在 case 的表達(dá)式里面,實(shí)際運(yùn)行卻是沒問題的:
- command_split("make")
- command_split("make clean")
- command_split("restart")
- command_split("rm a b c")
- # default make
- # make command found: clean
- # restarting
- # deleting files: ['a', 'b', 'c']
匹配后剩余的部分可以變成一個變量,不得不服還可以這樣用。
再看一個:
- def match_capture_subpattern(command):
- match command.split():
- case ["go", ("north" | "south" | "east" | "west") as direction]:
- print(f"going {direction}")
你看還能結(jié)合 as 使用。牛逼不牛逼?
最后再看一個:
- match point:
- case Point(x, y) if x == y:
- print(f"The point is located on the diagonal Y=X at {x}.")
- case Point(x, y):
- print(f"Point is not on the diagonal.")
case 里面還可以再用 if,牛逼不牛逼?
這些花樣招式,除了增加程序員的心智負(fù)擔(dān),能有啥好處?我簡簡單單的 if elif 就搞定了,可讀性還高。再說了這 match 并性能上的提升,甚至有時候還更慢,何苦呢?
Python 為什么一開始就沒有 match,現(xiàn)在都 2021 年了,你新增個 match,是忘了初心嗎?
3、新的類型提示,笑死我了
Python3.9 這樣寫的:
- from typing import Union
- a: Union[int, str] = 1
Python3.10 可以這樣寫:
- a: str | int = 1
講真,即使你換成 |,我也不大可能會用。類型提示是學(xué)習(xí)人家靜態(tài)語言的優(yōu)勢,提示程序的可讀性和可維護(hù)性,修改代碼時別傳錯了變量類型。
何況 Python 解釋器根本不檢查類型提示是否有錯誤,純屬自娛自樂:
- >>> def fun(x :int) -> str:
- ... return x
- ...
- >>> print(fun('asf'))
- asf
- >>>
如果一個變量可以有很多類型,還提示個屁啊?提示的多了,還不如不提示,本來就是動態(tài)語言嘛。自己玩自己,搞笑吧,哈哈哈哈。
我用類型提示最多就用一個類型,要是超過一個類型,我就不提示?;蛘咦约盒薷拇a,用得著那么多類型么?
第三、還不是很穩(wěn)
Python 3.9.0 于 2020 年 10 月發(fā)布。3.9.1 于 2 個月后發(fā)布,其中包含一長串錯誤修正。同樣的,Python3.10.x 也可能會有一些錯誤修正,讓它再飛一會兒。
Python 3.10 有了新的語法:match-case,但是一些格式化工具或 IDE 可能還不支持。即使支持,你需要升級他們。
總之 Python3.10.0 才一個月,還不是很穩(wěn)。
那你可能會問了,什么時候算穩(wěn)?
我覺得比最新版本低 1-2 個是最好的選擇,比如 Python3.10 發(fā)布了,那么可以考慮升級到 Python3.8 或 Python3.9,因?yàn)榇藭r這些版本已經(jīng)足夠穩(wěn)定。
另一方面,除非你用的版本宣告了不支持安全更新的時間,或者報告了 bug,否則,你可以一直不更新。比如說,Python 3.6 將在 2021 年 12 月結(jié)束安全更新,此時應(yīng)該升級到 Python3.7 或以后的版本。
最后的話
基于以上三點(diǎn),我決定不會更新 Python3.10。當(dāng)然,Python3.10 也有比較好的新特性,比如更友好的報錯提示,當(dāng)你的括號、引號未閉合時,會拋出更加清晰明了的錯誤。
很喜歡 Python 之禪的那兩句:簡單勝過復(fù)雜,明確優(yōu)于隱晦。希望 Python 的更新也能保持 Python 之禪的初心。