Type hints oder duck typing?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
zegru
User
Beiträge: 49
Registriert: Freitag 9. Oktober 2020, 09:22

In Python gibt es ja die Möglichkeit, Funtkionsparameter auf zwei verschiedene Arten zu definieren: Nämlich einfach nur als "vorhanden und benannt", wodurch man dann mittels Duck typing darauf zugreift, oder mittels type hinting nur Daten eines bestimmten Typs zulässt.
Welche der beiden sollte man wählen? Wodurch schießt man sich auf Dauer weniger ins Knie? Was bereut man im Nachhinein weniger? Was ist am ehesten pythonic?
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Seit wann lässt type hinting nur einen Typ zu? Ich hatte das eher als Hinweis verstanden. Kann man befolgen, muss man aber nicht. Manche IDE weisen ggf. extra drauf hin.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist immer Duck-Typing. Die Typen sind nur Dekoration, fuer IDEs.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Python ist dynamisch typisiert, daran ändern Type Hints _nichts_ - richtigerweise. Sonst würde sich ja eine Eigenschaft der Sprache grundlegend ändern.

Type Hints sind, wie der Name schon sagt, Hinweise, welchen Typen an Parameter / Argument haben soll und was die Funktion oder Methode zurück liefert. Den Code kann man dann mit einem Type Checker prüfen lassen und der moniert dann mögliche Fehler / Abweichungen.

Zur Laufzeit sind Type Hints egal, weil die ignoriert werden. Zitat aus https://docs.python.org/3/library/typing.html: "Note: The Python runtime does not enforce function and variable type annotations."

Ob du Type Hints nutzt oder nicht liegt am Ende bei dir. Ins Knie schießt du dir auf keinen Fall, weil siehe oben.

Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zegru: Es gibt nur eine Art Parameter für Python zu definieren: vorhanden und benannt. Man kann da zusätzlich noch Annotationen dran pappen, die Python aber herzlich egal sind. Das sind *Hinweise*, Englisch „hints“, für den Leser.

Wenn man Typannotationen macht, sollte man die auch engmaschig *prüfen*, mit einer geeigneten Software. Denn falsche Typannotationen sind noch schlimmer als falsche Kommentare, weil man den Typannotationen als Leser wirklich fest glaubt, weil die ja automatisiert auf Korrektheit geprüft wurden, also im Gegensatz zu Kommentaren stimmen müssen. Wobei wie gesagt: das macht nicht Python, das muss der Autor selber aktiv machen. Sich eines der mehreren Projekte mit denen man das tun kann, aussuchen, und aktiv in den Arbeitsablauf integrieren. Falls die IDE das nicht schon als Voreinstellung eingebaut hat.

Letztendlich ist es Geschmackssache. Es hat Vor- und Nachteile. Man muss beides nicht 100% durchziehen, weil die Typannotationen ja nirgends erzwungen werden. Und man kann nachträglich welche hinzufügen oder auch welche wegnehmen.

Übrigens: auch wenn man Typannotationen 100% durchziehen will, wird man sinnvollerweise nicht blind überall eine Annotation dran pappen, sondern nur dort wo Mensch und Maschine das nicht von den Werten herleiten können. Niemandem ist bei einem ``answer: int = 42`` irgendwie geholfen. Da gilt wie bei Kommentaren, das man nicht das offensichtliche noch mal da hinschreibt.

Ich persönlich mag sie nicht, weil sie mir nicht wirklich helfen, aber Zeit beim schreiben verbrauchen. Nicht nur wegen dem Schreibvorgang selbst, sondern weil das Thema gar nicht sooo einfach ist, wenn man Typen nicht unnötig stark einschränken will, und weil die Typinformationen auch nervige Zusatzinformation sein können, die man extra überlesen oder gar verstehen muss, wenn sie nicht trivial sind. Das führt dann öfter auch mal dazu, dass formale Argumente nicht mehr in eine Zeile passen. Ich bin ja nicht von Java & Co zu Python gekommen, habe mich über's Duck-Typing gefreut, um dann doch wieder Typannotationen zu schreiben. 😂
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Typannotationen und Duck Typing schließen sich nicht aus. Zum Beispiel, wenn man `typing.Protocol` oder eine abstrakte Basisklasse als Typ benutzt. Aber das macht den von __blackjack__ angesprochenen Aspekt, dass das Schreiben und Lesen der Typannotationen Zeit braucht und vom „wesentlichen“ ablenkt, noch schlimmer, weil man mehr Typannotationscode schreiben und lesen muss.

Und dann gibt es immer wieder Fälle, wo der Typchecker den Code nicht verstehen kann, und man eigentlich unnötige `assert`s schreiben muss, um dem Typchecker durch einen Runtimecheck zu beweisen, dass der statische Typ passt (!).

Ich persönlich finde, dass Typannotationen schon einen Wert haben können, aber für mich persönlich erst, wenn ich nicht mehr den ganzen Code im Kopf halten kann, und wenn ich dann existierenden Code anpassen muss. Und dann müssen es gute Typannotationen sein, wo man nochmal mehr Aufwand hat, die zu schreiben.
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Beim Nutzen von Typ-Annotationen greife ich gerne auf die Typ-Definitionen aus dem ``collections.abc`` Modul zu. Statt ``list`` kann ich dann ``Sequence`` als Typen eintragen oder anstatt ``dict`` nehme ich ``Mapping``. Damit hat man gewissermaßen eine Mischung aus festen Typ-Angaben und dennoch einigen Freiheiten für den Benutzer.
zegru
User
Beiträge: 49
Registriert: Freitag 9. Oktober 2020, 09:22

Aha. Es ist in der Tat nur ein unverbindlicher Hinweis, wie ich ausprobiert habe.
Ich benutze das aber hauptsächlich als Dokumentation für mich selber, um älteren Code von mir besser verstehen zu können. Also eher für mich als für den Rechner.
Aber es interessiert mich, ob man Python dazu bringen kann, wenigstens eine Warnung auszugeben, wenn der Typ nicht passt. Im Moment meckern ja echt nur manche IDEs, aber das Ausführen macht dann ohne Meckern eventuell Blödsinn. Also dass man den Typ nicht nur per assert festnagelt, sondern dass wenigstens gewarnt wird, dass da etwas stinkt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn man bestimmen Systeme wie pydantic und FastAPI (baut darauf glaube ich auf) benutzt, dann in Grenzen ja. Es ist aber eine extra Laufzeitsteuer, und eine globale Flagge, die alles anschaltet, gibt es nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13117
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@zegru: Warum soll Python das machen? Es gibt doch *mehrere* Programme die statisch prüfen. Der Autor der solche Annotationen anbringt benutzt ja mindestens eines davon, automatisiert, und regelmässig. Wenn er das nicht macht, sollte er keine Annotationen schreiben. Also kann man ja davon ausgehen das Annotationen und Code zusammenpassen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1021
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

__deets__ hat geschrieben: Freitag 26. Januar 2024, 19:15 Wenn man bestimmen Systeme wie pydantic und FastAPI (baut darauf glaube ich auf) benutzt, dann in Grenzen ja. Es ist aber eine extra Laufzeitsteuer, und eine globale Flagge, die alles anschaltet, gibt es nicht.
Weil die Steuer so hoch ist, sind kritische Teile in Rust entwickelt worden. Vorher war das wohl auch alles Python-Code.
Ein weiteres Beispiel ist z.B. ruff format vs black.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Interessant. Und auch ein bisschen krass. Rust ist schon nicht ganz einfach, darum würde ich das jetzt nicht blanko als Python Ersatz ins Spiel bringen, wenn man Typen haben will. Aber Swift oder sowas, das etwas weniger strikt, und GCd ist, wäre wahrscheinlich eine Alternative.
Antworten