いくつかのインターフェースを書くために、抽象基本クラスで Python の型注釈を試しています。 および の可能な型に注釈を付ける方法はあります*args
か**kwargs
?
たとえば、関数への適切な引数が 1 個int
または 2int
個の のいずれかであることをどのように表現するのでしょうか。type(args)
は を返すのでTuple
、型を として注釈付けするのではないかと考えましたUnion[Tuple[int, int], Tuple[int]]
が、これは機能しません。
from typing import Union, Tuple
def foo(*args: Union[Tuple[int, int], Tuple[int]]):
try:
i, j = args
return i + j
except ValueError:
assert len(args) == 1
i = args[0]
return i
# ok
print(foo((1,)))
print(foo((1, 2)))
# mypy does not like this
print(foo(1))
print(foo(1, 2))
mypy からのエラー メッセージ:
t.py: note: In function "foo":
t.py:6: error: Unsupported operand types for + ("tuple" and "Union[Tuple[int, int], Tuple[int]]")
t.py: note: At top level:
t.py:12: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:14: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:15: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:15: error: Argument 2 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
mypy が関数呼び出しにこれを好まないのは当然です。tuple
呼び出し自体に があることを前提としているからです。展開後の追加でも、理解できない入力エラーが発生します。
*args
およびの適切な型をどのように注釈付けするのでしょうか**kwargs
?
ベストアンサー1
可変位置引数 ( *args
) および可変キーワード引数 ( ) の場合、そのような引数の1 つ**kw
に対して期待される値を指定するだけで済みます。
から任意の引数リストとデフォルトの引数値のセクション型ヒントPEPの:
任意の引数リストにも型注釈を付けることが可能なので、定義は次のようになります。
def foo(*args: str, **kwds: int): ...
は許容され、たとえば、次のすべてが有効な型の引数を持つ関数呼び出しを表すことを意味します。
foo('a', 'b', 'c') foo(x=1, y=2) foo('', z=0)
したがって、メソッドを次のように指定します。
def foo(*args: int):
ただし、関数が 1 つまたは 2 つの整数値しか受け入れることができない場合は、 を*args
まったく使用せず、明示的な位置引数 1 つと 2 番目のキーワード引数を使用します。
def foo(first: int, second: Optional[int] = None):
これで、関数は実際には 1 つまたは 2 つの引数に制限され、指定されている場合は両方とも整数である必要があります。*args
常に0 以上を意味し、型ヒントによってより具体的な範囲に制限することはできません。