記住Python變數型別的三種方式

青南發表於2017-06-11

Python作為一門動態語言,其變數的型別可以自由變化。這個特性提高了程式碼的開發效率,卻也增加了閱讀程式碼和維護程式碼的難度。

假設有一個變數is_request_finished,從名字上來看,這個變數的值應該為True或者False,在寫程式碼的時候,最初也確實是這樣定義的。但是可能由於某些原因,在某一次賦值的時候,is_request_finished = 'True'。此時,如果程式碼的單元測試不夠完善,那麼if is_request_finishedis_request_finished = Trueis_request_finished = 'True'的時候都成立,問題被隱藏了。但是當is_request_finished = 'False'的時候,由於'False'作為一個非空字串,就會使得if is_request_finished 依然成立,從而使程式的行為發現異常。

單個變數的型別異常也許還容易發現,但是如果變數是放在字典或者列表裡面,那就比較麻煩了。假設需要儲存一段個人資訊,於是建立了下面這樣一個列表套字典的資料結構:

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
            }
}]複製程式碼

這種方式開發起來非常的快速而方便,但是其他人甚至是開發者自己在一段時間以後讀程式碼,都會有一種想抽死自己的衝動。因為根本不知道這個變數裡面儲存的是什麼東西。

針對以上問題,常見的解決辦法有三種。

Type Hints 與 Variable Annotations

PEP 484中,引入了Type Hints,在PEP 526中引入了Variable Annotations。它使得Python 3.6及以後的Python 程式碼擁有了“宣告”變數型別的能力。這裡的“宣告”之所以會打引號,是因為這個宣告是給IDE和人看的。這個宣告對 Python 的直譯器無效。

Type Hints

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複製程式碼

如果直接執行,其執行效果如下圖所示:

記住Python變數型別的三種方式

現在假設傳遞一個不是字串的變數給upload函式,此時PyCharm就會提示型別有問題,如下圖所示:

記住Python變數型別的三種方式

但提示歸提示,強行執行也是沒有問題的。這就說明Type Hints主要是給IDE和人用的,直譯器並不會關心型別正不正確。

如果修改這個函式的返回值,讓它不返回True 或者False,PyCharm 也會發出警告:

記住Python變數型別的三種方式

Type Hints的官方文件,可以參閱:typing — Support for type hints

Variable Annotations

對於Variable Annotations,如下圖所示,雖然目前PyCharm還不能很好地提示變數型別不對,但是人在讀程式碼的時候,還是會起到一定的幫助。

記住Python變數型別的三種方式

除了這種寫法外,Variable Annotations還支援把型別寫在註釋中,如下圖所示:

記住Python變數型別的三種方式

雖然PyCharm不能起到很好的提示作用,但是可以使用一個第三方庫mypy來對程式碼做靜態檢查,其執行效果如下圖所示,可以發現賦值的型別與宣告的型別不一致(expression has type "str", variable has type "bool", 表示式的型別為“str”,變數的型別是“bool”)。

記住Python變數型別的三種方式

關於Variable Annotations的更多用法,可以參閱:Syntax for Variable Annotations
關於Mypy,可以參閱它的官方文件:Mypy documentation

docstring

在docstring來標註變數的型別,如下圖所示:

記住Python變數型別的三種方式

這種寫法可以用來提示一個函式,或者一個類它裡面的各個變數的情況。但是詳細程度需要看開發者有沒有耐心把這個註釋寫清楚。

Bean

這種方法來自與Java Bean的思想,它主要用來解決列表套字典,字典套字典,字典套列表,列表套列表這種深層的巢狀關係。關於這個方法,請參閱另一篇文章:可愛的豆子——使用Beans思想讓Python程式碼更易維護

相關文章