2017-09-22 47 views
0

我有一個函數返回一個2元組,但可以是一個3元組。我如何用類型註釋來描述這個?Python類型註解:將元組中的元素標記爲可選

例如:

from typing import Tuple 

def example(i): 
    # type: (int) -> Tuple[int, int, <what to put here?>] 
    if i < 10: 
     return (i, i+1, 1) 
    else: 
     return (i, i+1) 

我可以使用聯盟像下面,但它似乎很凌亂。

# type: (int) -> Union[Tuple[int, int], Tuple[int, int, int]] 
+1

這些是2種不同的類型。工會可能是最合乎邏輯的。 – Carcigenicate

回答

2

正如評論中指出的那樣,工會可能是更好的方法。如果簽名看起來雜亂無章,你可以使用type aliases像這樣:

from typing import Tuple, Union 

MyType = Union[Tuple[int, int], Tuple[int, int, int]] 

def example1(i): 
    # type: (int) -> MyType 
    ...snip... 

另一種方法是使用"indefinite length" Tuple type。你基本上會放棄對元組的確切長度進行編碼,但作爲交換,可以規範返回類型並避免這種聯合。 (如果你的代碼的確依賴於的長度,這可能不是最好的辦法)。

def example2(i): 
    # type: (int) -> Tuple[int, ...] 
    ...snip... 

但是,更激烈的方法是考慮重構您的代碼以避免此類情況。

畢竟,如果你回到這兩種不同的類型,你的函數的調用者很可能將需要反正檢查長度,對不對?

在這種情況下,一個想法是放棄返回一個元組,而是返回一個NamedTuple或一個自定義類,它們都有一個可選字段。然後,您可以將您的「長度」檢查轉換爲「該字段設置爲無」檢查。

我想,在某種意義上說,NamedTuple方法也滿足的方式你原來的要求,只要你不介意你的轉換元組/會增加開銷。

from typing import NamedTuple, Optional 

MyType2 = NamedTuple('MyType2', (
    ('x', int), 
    ('y', int), 
    ('z', Optional[int]), 
)) 

class MyType3(object): 
    def __init__(self, x, y, z): 
     # type: (int, int, Optional[int]) -> None 
     self.x = x 
     self.y = y 
     self.z = z 

(一旦PEP 557被接受並融入了語言中的「自定義類」的方式將可能是更優雅)。

另一種方法是到了分裂您功能分爲兩個,如果你提前知道你希望哪種元組的時間。然後,你可以調用適當類型的函數。

+0

謝謝您的詳細解答。 –