編者按:Feedly聯(lián)合創(chuàng)始人、大數(shù)據(jù)與機(jī)器學(xué)習(xí)主管Kireet Reddy分享了對(duì)Python類(lèi)型提示的看法。
升級(jí)到Python 3.6后,突然發(fā)現(xiàn)Python通過(guò)typing模塊加入了類(lèi)型提示。我得承認(rèn),我并不非常熟悉python社區(qū),但是我覺(jué)得這樣一種語(yǔ)言特性應(yīng)該會(huì)引起不小的反響。
不管怎么說(shuō),我對(duì)這個(gè)新特性非常滿意。在我職業(yè)生涯的大部分時(shí)間里,我在Java這個(gè)靜態(tài)類(lèi)型的世界中工作,python的類(lèi)型提示多少提供了一些我很懷念的必需結(jié)構(gòu)。
Python的類(lèi)型系統(tǒng)
Python是一個(gè)動(dòng)態(tài)類(lèi)型語(yǔ)言,所謂的“鴨子類(lèi)型”。使用Python編程時(shí),動(dòng)態(tài)類(lèi)型大概是一把至為鋒利的雙刃劍。
基本上這意味著,Python并不會(huì)在編譯步驟預(yù)先檢查所有使用的類(lèi)型是合法的,Python程序?qū)⒗^續(xù)愉快地運(yùn)行下去,直到運(yùn)行不下去為止,這時(shí)它會(huì)拋出一個(gè)TypeError。例如,下面這段Java代碼編譯不過(guò):
publicstaticint add(int a, int b) { return a+b;}
...
add(1, "1");
Java編譯器會(huì)立即抱怨傳入了一個(gè)不兼容的類(lèi)型。然而,你最喜歡的python IDE一點(diǎn)也不會(huì)抱怨這段等價(jià)的Python代碼:
def add(a,b):
return a+b
...
add(1,"1")
你需要運(yùn)行代碼,才能碰到報(bào)錯(cuò)(整型和字符串無(wú)法相加)。
這真是糟糕。但是看看這個(gè):
>>> add(‘hello’, ‘world’)
‘helloworld’
>>> add([1,2,3], [4,5,6])
[1, 2, 3, 4, 5, 6]
好吧,看來(lái)動(dòng)態(tài)類(lèi)型也不完全是壞事。這同樣適用于類(lèi),只要對(duì)象存在恰當(dāng)?shù)姆椒?,python代碼可以直接工作,無(wú)需使用接口:
classDog(object):
def talk(self, quietly):
return'woof'if quietly else'BARK'
classCat(object):
def talk(self, quietly):
return'purr'if quietly else'YOWL'
def speak(a, quietly):
print(a.talk(quietly))
>>> speak(Dog())
woof
>>> speak(Cat())
meow
妙!少打很多字,代碼非常凝練。
問(wèn)題
在python項(xiàng)目的起初幾周這讓人感覺(jué)良好。不過(guò)接下來(lái)一周你可能離開(kāi)這個(gè)項(xiàng)目去改進(jìn)以前寫(xiě)的另一些代碼?;蛘吣阈枰鸵粋€(gè)同事一起編程。
過(guò)了一段時(shí)間你回頭看代碼的時(shí)候,或者同事看你的代碼的時(shí)候,看到speak(x)這行會(huì)覺(jué)得x太含糊。于是決定跳轉(zhuǎn)到speak的定義,結(jié)果看到了a.talk。下面就沒(méi)法進(jìn)一步跳轉(zhuǎn)到定義追蹤下去了,需要手動(dòng)搜索查看哪些地方實(shí)現(xiàn)了talk這一方法,接著還需要查看這些方法做了什么,嘗試推斷出speak在talk上施加的一般契約。
解決方案
類(lèi)型提示讓你可以提供更多的上下文。重寫(xiě)上面的代碼:
classDog(Animal):
def talk(self, quietly: bool) -> str:
return'woof'if quietly else'BARK'
classCat(Animal):
def talk(self, quietly: bool) -> str:
return'purr'if quietly else'YOWL'
def speak(a:Union[Dog, Cat], quietly: bool) -> None:
print(a.talk(quietly))
你可能已經(jīng)注意到了,類(lèi)型提示位于冒號(hào)和箭頭之后。注意它傳遞的額外信息。現(xiàn)在我們一眼就能看到speak期望Dog或Cat,而布爾值標(biāo)記指明是否應(yīng)該小聲說(shuō)話(返回小寫(xiě)字母)。如果我們期望將來(lái)有更多說(shuō)話者的類(lèi)型,那么這種寫(xiě)法會(huì)變得累贅嗎?會(huì),但這大概意味著我們應(yīng)該引入基類(lèi)。
沒(méi)有類(lèi)型提示,基本上很難編寫(xiě)不言自明(self-documenting)的代碼。你將不得不重度依賴(lài)極好的命名,一絲不茍的注釋?zhuān)€有代碼的清潔程度。這其實(shí)是相當(dāng)高的門(mén)檻。
一個(gè)額外的好處是,PyCharm等許多IDE支持類(lèi)型提示,如果你沒(méi)有傳入恰當(dāng)?shù)膮?shù),會(huì)通過(guò)下劃曲線標(biāo)出錯(cuò)誤。
我強(qiáng)烈建議在新代碼中使用類(lèi)型提示,接著逐漸更新老代碼。它們不僅為你節(jié)省了一些閱讀代碼的時(shí)間,更重要的是減輕了記住你所有的變量應(yīng)該是什么類(lèi)型的心智負(fù)擔(dān)。
如果你想了解更多關(guān)于類(lèi)型提示的內(nèi)容,請(qǐng)查看python文檔。升級(jí)到Python 3.6后我們?cè)贔eedly強(qiáng)調(diào)了類(lèi)型提示的重要性,后來(lái)我收到了這么一條slack消息:
(譯文:加入feedly前我并不知道python有類(lèi)型提示。有了類(lèi)型提示,閱讀其他人的代碼要容易太多?。?/p>
一切如你所想地工作的時(shí)候,感覺(jué)真不錯(cuò)。
-
代碼
+關(guān)注
關(guān)注
30文章
4900瀏覽量
70722 -
編譯器
+關(guān)注
關(guān)注
1文章
1662瀏覽量
50208 -
python
+關(guān)注
關(guān)注
56文章
4827瀏覽量
86715
原文標(biāo)題:給Python加上額外的類(lèi)型提示值得嗎?
文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Python中常用的數(shù)據(jù)類(lèi)型
總結(jié):一文了解Python中的數(shù)字類(lèi)型
python的數(shù)據(jù)類(lèi)型有哪些?
2.2 python字符串類(lèi)型
python常見(jiàn)異常類(lèi)型
Python數(shù)據(jù)類(lèi)型有幾種
python字典類(lèi)型的使用和注意事項(xiàng)

python教程之變量和簡(jiǎn)單數(shù)據(jù)類(lèi)型

Python并不是弱類(lèi)型語(yǔ)言

循序漸進(jìn)學(xué)Python之?dāng)?shù)值類(lèi)型
2.2 python字符串類(lèi)型
Python的數(shù)據(jù)類(lèi)型與變量賦值
Python最基本內(nèi)置數(shù)據(jù)類(lèi)型(1)

評(píng)論