2016-10-05 35 views
9

我使用新的Python 3.5模塊typing,它一直很歡樂。打字模塊 - 字符串文字類型

我想知道如何根據確切的字符串文字來指定一個類型。例如,一個函數保證返回四個字符串之一 - 「北」,「西」,「東」,「南 - 我們如何表達作爲特定類型變量,而不是僅僅str

我通過文件看,找到Union類型和TypeVar功能,但無法找到答案

表達這個問題的一個例子功能:

def compute_quadrant(x: int, y: int) -> str: 
    if x > 0 and y > 0: 
     return 'I' 
    elif x < 0 and y > 0: 
     return 'II' 
    elif x < 0 and y < 0: 
     return 'III' 
    elif x > 0 and y < 0: 
     return 'IV' 

而不是僅僅返回str,我喜歡返回一個更具體的類型,它是四個值之一 - "I","II","III""IV"

在Typescript中,可以這樣做:type Quadrant = "I" | "II" | "III" | "IV" - 這個用例中有typing模塊有什麼好的Python糖嗎?

+5

與打字無關,但你認爲'enum'? –

+0

我可以問,你爲什麼需要這樣的東西?因爲類型註釋是爲查看代碼的文本編輯器和程序員製作的。如果你可以限制函數可能返回的元素的範圍,那麼你絕對可以通過查看代碼來說。 –

+0

也許這個特定的函數沒有概述用例(因爲它簡單直接),但是在編寫代碼時,我想盡可能地爲我的對等提供儘可能多的上下文。在處理數據和對對象執行復雜操作時,我希望能夠提供非常嚴格和精確的類型。此外,分析工具能夠根據類型找到優化點 - 例如永遠不會被擊中的代碼路徑或明顯的錯誤。 – fructosewizard

回答

1

無視您詢問的typing模塊,您的問題的一種解決方案可能是使用Enum,正如多個註釋中所設想的那樣。代碼如下:

from enum import Enum 

class Quadrant(Enum): 
    I = 1 
    II = 2 
    III = 3 
    IV = 4 

def compute_quadrant(x: int, y: int) -> Quadrant: 
    if x > 0 and y > 0: 
     return Quadrant.I 
    elif x < 0 and y > 0: 
     return Quadrant.II 
    elif x < 0 and y < 0: 
     return Quadrant.III 
    elif x > 0 and y < 0: 
     return Quadrant.IV 
    # return None # this is what happens without an else clause! 

if __name__ == "__main__": 
    quad = compute_quadrant(1, -1) 
    print(quad, type(quad))    # -> Quadrant.IV <enum 'Quadrant'> 
    print(quad.name, type(quad.name)) # -> IV <class 'str'> 
    print(quad.value, type(quad.value)) # -> 4 <class 'int'> 

正如你所看到的,你可以使用枚舉名和值。該名稱是您要求的字符串之一。

我在這裏看到的一個問題是函數中的missing else子句和mypy當前接受None作爲Quadrant的有效返回值的行爲。這應該手動處理。