Optional[...]
ist eine Kurzschreibweise für Union[..., None]
, die dem Typprüfer mitteilt, dass entweder ein Objekt des bestimmten Typs erforderlich ist oder None
erforderlich ist. ...
steht für einen gültigen Typhinweis , einschließlich komplexer zusammengesetzter Typen oder eines oder Union[]
mehrerer Typen. Wann immer Sie ein Schlüsselwortargument mit Standardwert haben None
, sollten Sie verwenden Optional
.
Für Ihre beiden Beispiele haben Sie also dict
und list
Containertypen, aber der Standardwert für das a
Schlüsselwortargument zeigt, dass None
dies ebenfalls zulässig ist. Verwenden Sie daher Optional[...]
:
from typing import Optional
def test(a: Optional[dict] = None) -> None:
def test(a: Optional[list] = None) -> None:
Beachten Sie, dass es zwischen der Verwendung von technisch keinen Unterschied Optional[]
auf eine Union[]
oder nur das Hinzufügen None
zu der Union[]
. Also Optional[Union[str, int]]
und Union[str, int, None]
sind genau das gleiche.
Persönlich würde ich mich immer daran halten , Optional[]
wenn der Typ für ein Schlüsselwortargument festgelegt wird, mit = None
dem ein Standardwert festgelegt wird. Dies dokumentiert den Grund, warum dies None
besser zulässig ist. Darüber hinaus ist es einfacher, das Union[...]
Teil in einen separaten Typalias zu verschieben oder das Optional[...]
Teil später zu entfernen, wenn ein Argument obligatorisch wird.
Angenommen, Sie haben
from typing import Optional, Union
def api_function(optional_argument: Optional[Union[str, int]] = None) -> None:
"""Frob the fooznar.
If optional_argument is given, it must be an id of the fooznar subwidget
to filter on. The id should be a string, or for backwards compatibility,
an integer is also accepted.
"""
Anschließend wird die Dokumentation verbessert, indem der Union[str, int]
Alias in einen Typ gezogen wird:
from typing import Optional, Union
SubWidgetId = Union[str, int]
def api_function(optional_argument: Optional[SubWidgetId] = None) -> None:
"""Frob the fooznar.
If optional_argument is given, it must be an id of the fooznar subwidget
to filter on. The id should be a string, or for backwards compatibility,
an integer is also accepted.
"""
Der Refactor zum Verschieben des Union[]
Alias wurde umso einfacher, Optional[...]
als er stattdessen verwendet wurde Union[str, int, None]
. Der None
Wert ist schließlich keine 'Subwidget-ID', er ist nicht Teil des Werts und None
soll das Fehlen eines Wertes kennzeichnen .
Randnotiz: Sofern Ihr Code nicht nur Python 3.9 oder höher unterstützen muss, möchten Sie vermeiden, die Standardbibliothekscontainertypen für Typhinweise zu verwenden, da Sie nichts darüber sagen können, welche Typen sie enthalten müssen. Also statt dict
und list
, Verwendung typing.Dict
und typing.List
sind. Und wenn Sie nur von einem Containertyp lesen , können Sie genauso gut jeden unveränderlichen abstrakten Containertyp akzeptieren. Listen und Tupel sind Sequence
Objekte, während dict
es sich um einen Mapping
Typ handelt:
from typing import Mapping, Optional, Sequence, Union
def test(a: Optional[Mapping[str, int]] = None) -> None:
"""accepts an optional map with string keys and integer values"""
def test(a: Optional[Sequence[Union[int, str]]] = None) -> None:
"""accepts an optional sequence of integers and strings
# print(a) ==> [1, 2, 3, 4, 'a', 'b']
# or
# print(a) ==> None
In Python 3.9 und höher wurden alle Standardcontainertypen aktualisiert, um die Verwendung in Typhinweisen zu unterstützen (siehe PEP 585) . Aber , während Sie jetzt können verwenden dict[str, int]
oder list[Union[int, str]]
Sie noch möchten die ausdrucksvoller verwenden Mapping
und Sequence
Anmerkungen , um anzuzeigen , dass eine Funktion nicht die Inhalte werden mutiert (sie behandelt werden als ‚nur lesen‘), und dass die Funktionen funktionieren würde mit Jedes Objekt, das als Mapping bzw. Sequenz fungiert.
Dict
und tippenList
und schreibenOptional[Dict]
undOptional[List]
stattOptional[dict]
...list
unddict
kann für Typhinweise verwendet werden (vs.List
,Dict
). python.org/dev/peps/pep-0585Direkt aus den Dokumenten des mypy-Tippmoduls .
quelle