Verwenden von Liste/Tupel/etc. von der Eingabe vs. direkten Verweis auf den Typ als Liste/Tupel/etc

Lesezeit: 5 Minuten

Benutzeravatar von Markus Meskanen
Markus Meskanen

Was ist der Unterschied zur Verwendung List, Tupleusw. von typing Modul:

from typing import Tuple

def f(points: Tuple):
    return map(do_stuff, points)

Im Gegensatz zum direkten Verweis auf Pythons Typen:

def f(points: tuple):
    return map(do_stuff, points)

Und wann sollte ich eines über dem anderen verwenden?

Benutzeravatar von Martijn Pieters
Martijn Pieters

Bis Python 3.9 Unterstützung für Typhinweise mit Standardsammlungen hinzugefügtmussten Sie verwenden typing.Tuple Und typing.List wenn du dokumentieren wolltest, welcher typ das ist Inhalt der benötigten Container:

def f(points: Tuple[float, float]):
    return map(do_stuff, points)

Bis Python 3.8, tuple Und list hat das Sein nicht unterstützt benutzt als generische Typen. Das obige Beispiel dokumentiert, dass die Funktion f erfordert die points Argument, ein Tupel mit zwei zu sein float Werte.

typing.Tuple Das Besondere daran ist, dass Sie eine bestimmte Anzahl von erwarteten Elementen und den Typ jeder Position angeben können. Verwenden Sie Auslassungspunkte, wenn die Länge nicht festgelegt ist und der Typ wiederholt werden soll: Tuple[float, ...] beschreibt eine variable Länge tuple mit floatS.

Für typing.List und anderen Sequenztypen geben Sie generell nur den Typ für alle Elemente an; List[str] ist eine Liste von Zeichenfolgen beliebiger Größe. Beachten Sie, dass Funktionen bevorzugt übernommen werden sollten typing.Sequence als Argumente u typing.List wird normalerweise nur für Rückgabetypen verwendet; Im Allgemeinen würden die meisten Funktionen eine beliebige Sequenz annehmen und nur iterieren, aber wenn Sie a zurückgeben listgeben Sie wirklich einen bestimmten, veränderlichen Sequenztyp zurück.

Wenn Sie weiterhin Python 3.8 oder älteren Code unterstützen müssen, sollten Sie immer die auswählen typing Generika, auch wenn Sie die Inhalte derzeit nicht einschränken. Es ist einfacher, diese Einschränkung später mit einem generischen Typ hinzuzufügen, da die resultierende Änderung kleiner sein wird.

Wenn Sie einen benutzerdefinierten Containertyp implementieren und möchten, dass dieser Typ Generika unterstützt, ist dies möglich implementieren a __class_getitem__ Haken oder erben von typing.Generic (was wiederum implementiert __class_getitem__).

  • Was ist mit dem Vorteil von List[] über []. Wenn ich persönlich das erste schöner finde, habe ich aber kein Argument in einem Code-Review zum Beispiel 🙂

    – Samos

    25. Mai 2020 um 14:43 Uhr

  • @Samos Beide würden verwenden PEP 3107 Aber [] ist nicht beschrieben in PEP 484oder die Erweiterung PEPs. Wenn Sie den Standard nicht befolgen, erhalten Sie nicht die Vorteile von Tools, die das sind nur folgen Sie der Norm. ZB kann mypy nicht funktionieren.

    – Peilonrayz

    25. Mai 2020 um 15:38 Uhr

  • “Beachten Sie, dass Funktionen vorzugsweise typing.Sequence als Argumente und typing.List annehmen sollten, wird normalerweise nur für Rückgabetypen verwendet; im Allgemeinen würden die meisten Funktionen eine beliebige Sequenz annehmen und nur iterieren, aber wenn Sie eine Liste zurückgeben, geben Sie wirklich eine bestimmte, änderbarer Sequenztyp.” Warum sollten Funktionen keine Sequenz zurückgeben?

    – kolistivra

    12. August 2020 um 16:24 Uhr


  • @kolistivra: weil das einschränkt, was ein Aufrufer mit dem zurückgegebenen Listenobjekt machen kann. Alles, was erfordert, sagen wir, a veränderlich Sequenz akzeptiert den Rückgabewert nicht. Oder wenn etwas aus irgendeinem Grund speziell eine Liste erfordert, können Sie auch den Rückgabewert verwenden. Legen Sie Ihren Rückgabewert so spezifisch wie möglich fest.

    – Martijn Pieters

    12. August 2020 um 21:00 Uhr

  • Vergiss es nicht from typing import Tuple

    – Sparkofska

    27. September 2021 um 17:40 Uhr


Ab Python 3.9 (PEP 585) weiter tuple, list und verschiedene andere Klassen sind jetzt generische Typen. Verwenden Sie diese eher als ihre typing Gegenstück wird jetzt bevorzugt. Ab Python 3.9 können Sie jetzt einfach Folgendes tun:

def f(points: tuple[float, float]):
    return map(do_stuff, points)

Wenn Sie Ihre Typhinweise nicht auswerten müssen, können Sie diese Syntax in Python 3.7+ aufgrund von verwenden PEP 563.

from __future__ import annotations


def f(points: tuple[float, float]):
    return map(do_stuff, points)

Sie sollten immer dann wählen, nicht-typing generisch wann immer möglich wie die alten typing.Tuple, typing.List Und andere Generika sind veraltet und werden in einer späteren Version von Python entfernt.

Importieren Sie diese aus typing ist veraltet. Wegen PEP 563 und der Absicht, die Auswirkung der Eingabe auf die Laufzeit zu minimieren, generiert diese Verwerfung keine DeprecationWarnings. Stattdessen können Typprüfer vor einer solchen veralteten Verwendung warnen, wenn signalisiert wird, dass die Zielversion des geprüften Programms Python 3.9 oder neuer ist. Es wird empfohlen, diese Warnungen projektweit stumm zu schalten.

Die veraltete Funktionalität wird aus dem Typing-Modul in der ersten Python-Version entfernt, die 5 Jahre nach der Veröffentlichung von Python 3.9.0 veröffentlicht wird.

  • “Es wird jetzt bevorzugt, diese anstelle ihres Gegenstücks zu verwenden.” Ist es für öffentliche Python-Bibliotheken nicht sinnvoll, die typing Generika für 4 Jahre nach der Veröffentlichung von Python 3.9.0?

    – Mateen Ulhaq

    12. Januar 2021 um 2:36 Uhr


  • Ich widerspreche @MateenUlhaq nicht, aber kannst du uns sagen, warum es Sinn macht?

    – MinneapolisCoder9

    19. Januar 2022 um 22:44 Uhr

  • @MonkeySeeMonkeyDo Die Bibliotheken funktionieren also mit Python 3.0+. Während Sie einfach manuell was ausführen können __future__.annotations tut (def f(points: "tuple[float, float]")) funktioniert der Code nicht, wenn Sie die Typhinweise zur Laufzeit auswerten müssen.

    – Peilonrayz

    19. Januar 2022 um 22:52 Uhr

  • Beachten Sie, dass Sie eckige Klammern verwenden müssen – [ and ] – zum Tippen. Wenn du es versuchst tuple(float, float) Du wirst kriegen TypeError: tuple expected at most 1 argument, got 2

    – Codeananda

    31. Januar um 13:26 Uhr


1443290cookie-checkVerwenden von Liste/Tupel/etc. von der Eingabe vs. direkten Verweis auf den Typ als Liste/Tupel/etc

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy