2017-09-22 7 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... 

しかし、やや抜本的なアプローチは、このような状況を回避するためにコードを再構築することです。

結局のところ、これらの2つの異なるタイプを返す場合、関数の呼び出し元はおそらく長さをチェックする必要があるでしょうか?

この場合、タプルを返すことをあきらめ、その代わりに任意のフィールドを持つ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が受け入れられ、言語に統合されると、「カスタムクラス」アプローチは、おそらくよりエレガントになります)。

もう一つの方法は、あなたが期待しているタプルの種類を事前に知っているならば、関数を2つに分割することです。次に、適切な型の関数を呼び出すことができます。

+0

徹底的な回答ありがとうございます。 –

関連する問題