web-dev-qa-db-ja.com

型ヒントを使用して「nullable」戻り型を指定する方法

私が機能を持っていると仮定します:

def get_some_date(some_argument: int=None) -> %datetime_or_None%:
    if some_argument is not None and some_argument == 1:
        return datetime.utcnow()
    else:
        return None

Noneになり得るものの戻り値の型を指定するにはどうすればよいですか?

113
exfizik

Optional を探しています。

戻り値の型はdatetimedatetime.utcnow()から返される)またはNoneのいずれかであるため、Optional[datetime]を使用する必要があります。

from typing import Optional

def get_some_date(some_argument: int=None) -> Optional[datetime]:
    # as defined

入力に関するドキュメントから、Optionalは次の略記です:

Optional[X]Union[X, None]と同等です。

ここで、Union[X, Y]は、タイプXまたはYの値を意味します。


他の人がOptionalにつまずき、その意味を理解できないという懸念のために明示的にしたい場合は、常にUnionを使用できます。

from typing import Union

def get_some_date(some_argument: int=None) -> Union[datetime, None]:

しかし、これは良い考えだとは思いません。Optionalは指示的な名前であり、いくつかのキーストロークを節約します。

@ Michael0x2aのコメントで指摘されているように、Union[T, None]Union[T, type(None)]に変換されるため、ここでtypeを使用する必要はありません。

視覚的にはこれらは異なる場合がありますが、プログラムでは、どちらの場合も、結果はとまったく同じです; Union[datetime.datetime, NoneType]get_some_date.__annotations__に格納された型になります*

>>> from typing import get_type_hints
>>> print(get_type_hints(get_some_date))
{'return': typing.Union[datetime.datetime, NoneType],
 'some_argument': typing.Union[int, NoneType]}

*オブジェクトのtyping.get_type_hints属性に直接アクセスする代わりに、__annotations__を使用してオブジェクトを取得します。

178