So geben Sie den Rückgabetyp "nullable" mit Typhinweisen an

177

Angenommen, ich habe eine Funktion:

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

Wie gebe ich den Rückgabetyp für etwas an, das sein kann None?

exfizik
quelle

Antworten:

279

Du suchst Optional.

Da Ihr Rückgabetyp entweder datetime(wie von zurückgegeben datetime.utcnow()) sein kann oder NoneSie Folgendes verwenden sollten Optional[datetime]:

from typing import Optional

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

Aus der Dokumentation zum Tippen Optionalgeht hervor:

Optional[X]ist äquivalent zu Union[X, None].

Dabei Union[X, Y]bedeutet ein Wert vom Typ Xoder Y.


Wenn Sie aufgrund von Bedenken, über die andere stolpern könnten, explizit sein möchten Optionalund deren Bedeutung nicht erkennen, können Sie immer Folgendes verwenden Union:

from typing import Union

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

Aber ich bezweifle, dass dies eine gute Idee Optionalist, ein indikativer Name ist und ein paar Tastenanschläge erspart.

Wie in den Kommentaren von @ Michael0x2a Union[T, None]ausgeführt, wird Union[T, type(None)]so umgewandelt, dass hier keine Verwendung erforderlich ist type.

Optisch können diese unterschiedlich sein, aber programmatisch ist das Ergebnis in beiden Fällen genau das gleiche . Union[datetime.datetime, NoneType]wird der in get_some_date.__annotations__* gespeicherte Typ sein :

>>> 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]}

* Verwenden Sie typing.get_type_hintsdiese Option, um das __annotations__Attribut der Objekte abzurufen, anstatt direkt darauf zuzugreifen.

Dimitris Fasarakis Hilliard
quelle
9
Sie können vereinfachen, Union[datetime, type(None)]um Union[datetime, None]- gemäß PEP 484 wird die Verwendung Noneinnerhalb einer Typanmerkung immer als äquivalent zu behandelt type(None). (Die typingDokumentation wird Nonein den meisten Fällen tatsächlich verwendet , hier jedoch nicht, was ein Versehen ist.)
Michael0x2a
@ Michael0x2a wusste das nicht, interessant. Hinzugefügt :)
Dimitris Fasarakis Hilliard
4
Ich habe gerade einen Patch eingereicht , um dies zu beheben. Hoffentlich werden die Dokumente in naher Zukunft konsistenter!
Michael0x2a
1
Der Optional[T]Typ ist in der funktionalen Programmiergemeinschaft bekannt. Der Leser wird nicht nur wissen, dass dies bedeutet Union[T, None], sondern auch das Verwendungsmuster erkennen, dass die Funktion None zurückgeben soll, wenn keine aussagekräftige Antwort vorliegt, ein Fehler vorliegt oder das Ergebnis nicht gefunden wird.
Wochen