ChatGPT解决这个技术问题 Extra ChatGPT

How to specify "nullable" return type with type hints

Suppose I have a function:

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

How do I specify the return type for something that can be None?

bad naming applied in typing package. It could be Nullable[X] as an equivalent for Union[None, X]. Thus no need to explain that Optional is not for optional argument docs.python.org/3/library/typing.html#typing.Optional

D
Dimitris Fasarakis Hilliard

You're looking for Optional.

Since your return type can either be datetime (as returned from datetime.utcnow()) or None you should use Optional[datetime]:

from typing import Optional

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

From the documentation on typing, Optional is shorthand for:

Optional[X] is equivalent to Union[X, None].

where Union[X, Y] means a value of type X or Y.

If you want to be explicit due to concerns that others might stumble on Optional and not realize it's meaning, you could always use Union:

from typing import Union

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

But I doubt this is a good idea, Optional is an indicative name and it does save a couple of keystrokes.

As pointed out in the comments by @Michael0x2a Union[T, None] is tranformed to Union[T, type(None)] so no need to use type here.

Visually these might differ but programatically, in both cases, the result is exactly the same; Union[datetime.datetime, NoneType] will be the type stored in 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]}

*Use typing.get_type_hints to grab the objects' __annotations__ attribute instead of accessing it directly.


You can simplify Union[datetime, type(None)] to Union[datetime, None] -- according to PEP 484, using None within a type annotation is always treated as being equivalent to type(None). (The typing documentation actually uses None in most cases, but doesn't here, which is an oversight).
@Michael0x2a didn't know that, interesting. Added it :)
I went ahead and submitted a patch to fix this just now, so hopefully the docs will be more consistent about this in the near future!
The Optional[T] type is well-known in the functional programming community. The reader will not only know that it means Union[T, None], but will also recognise the use pattern that the function shall return None when there is no meaningful answer, there is an error, or the result is not found.
In Python 3.10 datetime | None can be used.
e
elano7

You could just use the vertical line datetime | None (similar to OR operator):

def get_some_date(some_argument: int=None) -> datetime | None:
   # rest of code

Note that the OR operator | is only available for type hinting in Python 3.10+
@PApostol Or in Python 3.7+ with from __future__ import annotations.