Union
ist genau für diese Situation bestimmt. Es schafft eine neue Art, die eine der Arten sein, können Sie angeben:
from typing import Union, List
def my_function(list_arg: Union[List[str], List[int]]) -> None: ...
Wenn Sie es häufig verwenden, eine Art Alias machen:
MyList = Union[List[str], List[int]]
def my_function(list_arg: MyList) -> None: ...
Ich würde nicht mit einer generischen Funktion empfehlen als @ user6269244 Antwort schlägt vor, es sei denn, Sie benötigen es aus einem bestimmten Grund. Obwohl T = TypeVar('T', int, str)
in einem einfachen Fall funktioniert, wird es restriktiver sein.
Beispiel: Angenommen, Sie so etwas wie dieses:
def apply_my_function(list_of_lists: List[MyList]) -> None:
# each item in list_of_lists is either a List[int] or List[str]
for arg in list_of_lists:
my_function(arg)
In diesem Code haben Sie keine chioce: Sie benötigen ein Union
(List[List[T]]
finden Sie sowohl eine Liste von int und einer Liste speichern, nicht zulassen, von str, weil T
nicht zwischen str
und int
in dem gleichen Ausdruck wechseln kann).
Aber da Sie Union
im Code verwenden, my_function
nennt, werden Sie auch Union
in der Signatur von my_function
selbst verwenden.
Darüber hinaus erhöhen Generics die Komplexität der Typen, und irgendwann stoßen Sie auf die Einschränkungen des Typsystems. So ist es besser, reservieren Generika für Fälle, in denen Sie wirklich benötigen, zum Beispiel, wenn Sie den Rückgabetyp von my_function
hängen vom Argument Typ wollen:
T = TypeVar("T", int, str)
# this can't be achieved with Union:
def my_function(list_arg: List[T]) -> T: ...
Ich denke, das ist vollständiger, also markiere ich es für andere, aber danke @ user6269244 - es löste das Problem gut genug für mich vorher! – vahndi