Python做爲一門動態語言,其變量的類型能夠自由變化。這個特性提升了代碼的開發效率,卻也增長了閱讀代碼和維護代碼的難度。javascript
假設有一個變量is_request_finished
,從名字上來看,這個變量的值應該爲True
或者False
,在寫代碼的時候,最初也確實是這樣定義的。可是可能因爲某些緣由,在某一次賦值的時候,is_request_finished = 'True'
。此時,若是代碼的單元測試不夠完善,那麼if is_request_finished
在 is_request_finished = True
和 is_request_finished = 'True'
的時候都成立,問題被隱藏了。可是當is_request_finished = 'False'
的時候,因爲'False'
做爲一個非空字符串,就會使得if is_request_finished
依然成立,從而使程序的行爲發現異常。html
單個變量的類型異常也許還容易發現,可是若是變量是放在字典或者列表裏面,那就比較麻煩了。假設須要保存一段我的信息,因而建立了下面這樣一個列表套字典的數據結構:java
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
}
}]複製代碼
這種方式開發起來很是的快速而方便,可是其餘人甚至是開發者本身在一段時間之後讀代碼,都會有一種想抽死本身的衝動。由於根本不知道這個變量裏面保存的是什麼東西。python
針對以上問題,常見的解決辦法有三種。express
在PEP 484中,引入了Type Hints,在PEP 526中引入了Variable Annotations。它使得Python 3.6及之後的Python 代碼擁有了「聲明」變量類型的能力。這裏的「聲明」之因此會打引號,是由於這個聲明是給IDE和人看的。這個聲明對 Python 的解釋器無效。數據結構
PyCharm如今已經能夠比較好地支持Type Hints了。例以下面這一段代碼:函數
def upload(url):
print(f'now upload a file to {url}')
return True複製代碼
模擬一段上傳文件的函數,上傳成功之後返回True。接收一個參數url
。在正常狀況下,這個url
應該是一個字符串。因而,使用Type Hints,代碼能夠變爲:單元測試
def upload(url: str) -> bool:
print(f'now upload a file to {url}')
return True複製代碼
若是直接運行,其運行效果以下圖所示:
測試
如今假設傳遞一個不是字符串的變量給upload
函數,此時PyCharm就會提示類型有問題,以下圖所示:
url
若是修改這個函數的返回值,讓它不返回True
或者False
,PyCharm 也會發出警告:
Type Hints的官方文檔,能夠參閱:typing — Support for type hints
對於Variable Annotations,以下圖所示,雖然目前PyCharm還不能很好地提示變量類型不對,可是人在讀代碼的時候,仍是會起到必定的幫助。
除了這種寫法外,Variable Annotations還支持把類型寫在註釋中,以下圖所示:
雖然PyCharm不能起到很好的提示做用,可是可使用一個第三方庫mypy
來對代碼作靜態檢查,其運行效果以下圖所示,能夠發現賦值的類型與聲明的類型不一致(expression has type "str", variable has type "bool", 表達式的類型爲「str」,變量的類型是「bool」)。
關於Variable Annotations的更多用法,能夠參閱:Syntax for Variable Annotations
關於Mypy,能夠參閱它的官方文檔:Mypy documentation
在docstring來標註變量的類型,以下圖所示:
這種方法來自與Java Bean的思想,它主要用來解決列表套字典,字典套字典,字典套列表,列表套列表這種深層的嵌套關係。關於這個方法,請參閱另外一篇文章:可愛的豆子——使用Beans思想讓Python代碼更易維護