Python作為一門動(dòng)態(tài)語言,其變量的類型可以自由變化。這個(gè)特性提高了代碼的開發(fā)效率黎烈,卻也增加了閱讀代碼和維護(hù)代碼的難度垒手。
假設(shè)有一個(gè)變量is_request_finished
蒜焊,從名字上來看,這個(gè)變量的值應(yīng)該為True
或者False
科贬,在寫代碼的時(shí)候泳梆,最初也確實(shí)是這樣定義的。但是可能由于某些原因榜掌,在某一次賦值的時(shí)候优妙,is_request_finished = 'True'
。此時(shí)憎账,如果代碼的單元測試不夠完善套硼,那么if is_request_finished
在 is_request_finished = True
和 is_request_finished = 'True'
的時(shí)候都成立,問題被隱藏了胞皱。但是當(dāng)is_request_finished = 'False'
的時(shí)候邪意,由于'False'
作為一個(gè)非空字符串,就會使得if is_request_finished
依然成立反砌,從而使程序的行為發(fā)現(xiàn)異常雾鬼。
單個(gè)變量的類型異常也許還容易發(fā)現(xiàn),但是如果變量是放在字典或者列表里面宴树,那就比較麻煩了策菜。假設(shè)需要保存一段個(gè)人信息,于是創(chuàng)建了下面這樣一個(gè)列表套字典的數(shù)據(jù)結(jié)構(gòu):
person_list = [{
'name': 'kingname',
'age': 23,
'sex': 'male'
'detail': {
'address': 'xxx',
'work': 'engineer',
'salary': 100000
}
},
{
'name': 'xiaoming',
'age': 65,
'sex': 'male'
'detail': {
'address': 'yyy',
'work': 'pm',
'salary': 0.5
}
}]
這種方式開發(fā)起來非常的快速而方便森渐,但是其他人甚至是開發(fā)者自己在一段時(shí)間以后讀代碼做入,都會有一種想抽死自己的沖動(dòng)。因?yàn)楦静恢肋@個(gè)變量里面保存的是什么東西同衣。
針對以上問題竟块,常見的解決辦法有三種。
Type Hints 與 Variable Annotations
在PEP 484中耐齐,引入了Type Hints浪秘,在PEP 526中引入了Variable Annotations。它使得Python 3.6及以后的Python 代碼擁有了“聲明”變量類型的能力埠况。這里的“聲明”之所以會打引號耸携,是因?yàn)檫@個(gè)聲明是給IDE和人看的。這個(gè)聲明對 Python 的解釋器無效辕翰。
Type Hints
PyCharm現(xiàn)在已經(jīng)可以比較好地支持Type Hints了夺衍。例如下面這一段代碼:
def upload(url):
print(f'now upload a file to {url}')
return True
模擬一段上傳文件的函數(shù),上傳成功以后返回True喜命。接收一個(gè)參數(shù)url
沟沙。在正常情況下河劝,這個(gè)url
應(yīng)該是一個(gè)字符串。于是矛紫,使用Type Hints赎瞎,代碼可以變?yōu)椋?/p>
def upload(url: str) -> bool:
print(f'now upload a file to {url}')
return True
如果直接運(yùn)行,其運(yùn)行效果如下圖所示:
現(xiàn)在假設(shè)傳遞一個(gè)不是字符串的變量給upload
函數(shù)颊咬,此時(shí)PyCharm就會提示類型有問題务甥,如下圖所示:
但提示歸提示,強(qiáng)行運(yùn)行也是沒有問題的喳篇。這就說明Type Hints主要是給IDE和人用的敞临,解釋器并不會關(guān)心類型正不正確。
如果修改這個(gè)函數(shù)的返回值杭隙,讓它不返回True
或者False
哟绊,PyCharm 也會發(fā)出警告:
Type Hints的官方文檔,可以參閱:typing — Support for type hints
Variable Annotations
對于Variable Annotations痰憎,如下圖所示票髓,雖然目前PyCharm還不能很好地提示變量類型不對,但是人在讀代碼的時(shí)候铣耘,還是會起到一定的幫助洽沟。
除了這種寫法外,Variable Annotations還支持把類型寫在注釋中蜗细,如下圖所示:
雖然PyCharm不能起到很好的提示作用裆操,但是可以使用一個(gè)第三方庫mypy
來對代碼做靜態(tài)檢查,其運(yùn)行效果如下圖所示炉媒,可以發(fā)現(xiàn)賦值的類型與聲明的類型不一致(expression has type "str", variable has type "bool", 表達(dá)式的類型為“str”踪区,變量的類型是“bool”)。
關(guān)于Variable Annotations的更多用法吊骤,可以參閱:Syntax for Variable Annotations
關(guān)于Mypy缎岗,可以參閱它的官方文檔:Mypy documentation
docstring
在docstring來標(biāo)注變量的類型,如下圖所示:
這種寫法可以用來提示一個(gè)函數(shù)白粉,或者一個(gè)類它里面的各個(gè)變量的情況传泊。但是詳細(xì)程度需要看開發(fā)者有沒有耐心把這個(gè)注釋寫清楚。
Bean
這種方法來自與Java Bean的思想鸭巴,它主要用來解決列表套字典眷细,字典套字典,字典套列表鹃祖,列表套列表這種深層的嵌套關(guān)系溪椎。關(guān)于這個(gè)方法,請參閱另一篇文章:可愛的豆子——使用Beans思想讓Python代碼更易維護(hù)