看完 Python3.10 的新特性,我決定仍不更新
Python3.10 在 2021 年的 10 月 3 號發布,目前已經過去 1 個月了,關于它的新特性相信大家已經有所耳聞,不過我決定仍然不更新,目前我在用的版本是 Python3.8,沒有任何不爽。下面說一說我不更新的理由。
第一、相關的庫可能還未跟進
如果你更新到了最新版本,已有的代碼能否在不修改的情況下仍然可以正常運行?是首先要考慮的問題。
Python 的第三方庫都是基于開源志愿者的勞動,他們免費做著非常有價值的工作,而且適配新的 Python 版本都需要時間。此外,由于升級涉及許多不同的群體,協調和發布需要更多時間。
第二、很多新特性沒使用價值
盤點一下 Python3.10 的那些沒什么用的新特性(個人觀點,可以留言來噴):
1、with 可以加括號了
比如:
- with (
- CtxManager1() as example1,
- CtxManager2() as example2,
- CtxManager3() as example3,
- ):
- ...
這一點,我基本用不到,也不清楚什么樣的情況需要這樣寫。要是有多個上下文,我就串著多寫幾個就是了,要是 example1 和 example2 有關系,我可以嵌套:
- with CtxManager1() as example1:
- with CtxManager2() as example2:
- ...
- ...
這樣寫不是層次更清晰嗎?
2、match case 就是花花腸子
Python3.10 新增了 match 和 case 軟關鍵字。什么是軟關鍵字?就是雖然是關鍵字,但是可以作為變量名,雖然如此,你肯定也不愿意讓 match 成為你的變量名了,因為這樣也是不會報錯的:
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")
這里有個 _ 表示誰也不匹配的情況,相當于一個默認值,但是 _ 本來是用來表示一個后續不再使用的變量的,假如這樣調用,雖然解釋的通,總感覺怪怪的:
- >>> _ = 42
- >>> match_errno(_)
- 42!
再來個復雜一點的:
- 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 的表達式里面,實際運行卻是沒問題的:
- 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}")
你看還能結合 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,牛逼不牛逼?
這些花樣招式,除了增加程序員的心智負擔,能有啥好處?我簡簡單單的 if elif 就搞定了,可讀性還高。再說了這 match 并性能上的提升,甚至有時候還更慢,何苦呢?
Python 為什么一開始就沒有 match,現在都 2021 年了,你新增個 match,是忘了初心嗎?
3、新的類型提示,笑死我了
Python3.9 這樣寫的:
- from typing import Union
- a: Union[int, str] = 1
Python3.10 可以這樣寫:
- a: str | int = 1
講真,即使你換成 |,我也不大可能會用。類型提示是學習人家靜態語言的優勢,提示程序的可讀性和可維護性,修改代碼時別傳錯了變量類型。
何況 Python 解釋器根本不檢查類型提示是否有錯誤,純屬自娛自樂:
- >>> def fun(x :int) -> str:
- ... return x
- ...
- >>> print(fun('asf'))
- asf
- >>>
如果一個變量可以有很多類型,還提示個屁啊?提示的多了,還不如不提示,本來就是動態語言嘛。自己玩自己,搞笑吧,哈哈哈哈。
我用類型提示最多就用一個類型,要是超過一個類型,我就不提示。或者自己修改代碼,用得著那么多類型么?
第三、還不是很穩
Python 3.9.0 于 2020 年 10 月發布。3.9.1 于 2 個月后發布,其中包含一長串錯誤修正。同樣的,Python3.10.x 也可能會有一些錯誤修正,讓它再飛一會兒。
Python 3.10 有了新的語法:match-case,但是一些格式化工具或 IDE 可能還不支持。即使支持,你需要升級他們。
總之 Python3.10.0 才一個月,還不是很穩。
那你可能會問了,什么時候算穩?
我覺得比最新版本低 1-2 個是最好的選擇,比如 Python3.10 發布了,那么可以考慮升級到 Python3.8 或 Python3.9,因為此時這些版本已經足夠穩定。
另一方面,除非你用的版本宣告了不支持安全更新的時間,或者報告了 bug,否則,你可以一直不更新。比如說,Python 3.6 將在 2021 年 12 月結束安全更新,此時應該升級到 Python3.7 或以后的版本。
最后的話
基于以上三點,我決定不會更新 Python3.10。當然,Python3.10 也有比較好的新特性,比如更友好的報錯提示,當你的括號、引號未閉合時,會拋出更加清晰明了的錯誤。
很喜歡 Python 之禪的那兩句:簡單勝過復雜,明確優于隱晦。希望 Python 的更新也能保持 Python 之禪的初心。