Woher wissen Sie, ob Funktionsrückgabe- und Argumenttypen vorhanden sind?

84

Obwohl mir das Enten-Typisierungskonzept von Python bekannt ist, habe ich manchmal Probleme mit der Art der Argumente von Funktionen oder der Art des Rückgabewerts der Funktion.

Wenn ich die Funktion selbst geschrieben habe, kenne ich die Typen. Aber was ist, wenn jemand meine Funktionen nutzen und aufrufen möchte, wie soll er / sie die Typen kennen? Normalerweise füge ich Typinformationen in die Dokumentzeichenfolge der Funktion ein (wie: "...the id argument should be an integer..."und "... the function will return a (string, [integer]) tuple.")

Aber ist es wirklich so, wie es gemacht werden soll, die Informationen in der Dokumentenkette nachzuschlagen (und als Codierer dort abzulegen)?

Bearbeiten: Während die meisten Antworten auf "Ja, Dokument!" Ich denke, dass dies für 'komplexe' Typen nicht immer sehr einfach ist.
Zum Beispiel: wie beschreiben prägnant in einem docstring , dass eine Funktion , eine Liste von Tupeln zurückgibt, wobei jedes Tupel der Form (node_id, node_name, uptime_minutes) , und daß die Elemente jeweils ein String, String und Integer?
Die PEP-Dokumentation zu docstring enthält hierzu keine Richtlinien.
Ich denke, das Gegenargument wird sein, dass in diesem Fall Klassen verwendet werden sollten, aber ich finde Python sehr flexibel, weil es erlaubt, diese Dinge mit Listen und Tupeln herumzugeben, dh ohne Klassen.

Rabarberski
quelle
2
Die kurze Antwort lautet "Ja". Die lange Antwort lautet "Ja, natürlich". Ich weiß nicht, ob Sie sich viel Python-Code angesehen haben, aber Sie sollten die Frage wahrscheinlich aktualisieren , um anzugeben, welche Pakete Sie tatsächlich verwenden, damit wir Sie zu Code weiterleiten können, den Sie lesen können, um zu sehen, wie die Dinge im Bibliothekscode von Ihnen ausgeführt werden Ich benutze es gerade.
S.Lott
@ S.Lott: Ich habe derzeit Probleme mit dem Mechanisierungspaket, aber ich denke, es ist nur (leider) schlecht dokumentiert.
Rabarberski
4
Python ist cool, weil Sie schnell viel Code schreiben können und sich nicht um alltägliche Dinge wie Rückgabetypen, Argumenttypen, Laufzeitleistung, Leute kümmern müssen, die Ihren Spaghetti-Code für die nächsten 10 Jahre verwenden und pflegen müssen usw. Seufz .
Jarmod

Antworten:

120

Nun, seit 2011 haben sich die Dinge ein wenig geändert! Jetzt gibt es Typen Hinweise in Python 3.5 , die Sie annotate Argumente verwenden können , und die Art Ihrer Funktion zurückzukehren. Zum Beispiel dies:

def greeting(name):
  return 'Hello, {}'.format(name)

kann jetzt so geschrieben werden:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

Wie Sie jetzt sehen können, gibt es eine Art optionale statische Typprüfung, die Ihnen und Ihrer Typprüfung hilft, Ihren Code zu untersuchen.

Für weitere Erklärungen schlage ich vor, einen Blick in den Blog-Beitrag zu Typhinweisen im PyCharm-Blog zu werfen .

Rsh
quelle
Beachten Sie, dass hier für Python 2.7 im selben PEP-0484 auch eine Syntax für Typhinweise vorgeschlagen wurde. Und es funktioniert in PyCharm, zumindest ab Version 2017.3.
Viddik13
1
Wenn die Begrüßungsfunktion mit genau derselben Definition ein Objekt vom Typ int zurückgibt, wird kein Fehler ausgelöst. Was nützt diese Art der Typprüfung, wenn Sie den Rückgabetyp explizit erwähnen, aber die Regel nicht befolgen und einen anderen Objekttyp zurückgeben?
Arashsyh
2
@Arashsyh: Ja, Sie haben Recht, Typhinweise verwandeln Python nicht in eine statisch typisierte Sprache. Es liegt an Ihnen, die richtigen Typen auf die richtige Weise zu verwenden. Und diese Typhinweise helfen Ihnen dabei, schneller zu entwickeln, Ihren Code selbst zu dokumentieren oder eine Warnung zu erhalten, wenn Sie etwas durcheinander bringen. Insbesondere wenn Sie PyCharm (oder eine ähnliche IDE) verwenden, werden Sie gewarnt, falls Sie einen anderen Typ verwenden, und es hilft bei einigen anderen Dingen. Ich empfehle, den in der obigen Antwort vorgeschlagenen Blog-Beitrag zu lesen.
Nerxis
Ist das rechnerisch schneller?
Bryce Wayne
17

So funktionieren dynamische Sprachen. Es ist jedoch nicht immer gut, besonders wenn die Dokumentation schlecht ist - hat jemand versucht, ein schlecht dokumentiertes Python-Framework zu verwenden? Manchmal muss man zum Lesen der Quelle zurückkehren.

Hier sind einige Strategien, um Probleme beim Tippen von Enten zu vermeiden:

  • Erstellen Sie eine Sprache für Ihre Problemdomäne
  • Dies wird Ihnen helfen, Dinge richtig zu benennen
  • Verwenden Sie Typen, um Konzepte in Ihrer Domänensprache darzustellen
  • Benennen Sie Funktionsparameter mithilfe des Vokabulars der Domänensprache

Auch einer der wichtigsten Punkte:

  • Halten Sie die Daten so lokal wie möglich!

Es sollten nur wenige gut definierte und dokumentierte Typen herumgereicht werden. Alles andere sollte beim Betrachten des Codes offensichtlich sein: Es gibt keine seltsamen Parametertypen aus der Ferne, die Sie nicht herausfinden können, wenn Sie in die Nähe des Codes schauen ...

Im Zusammenhang mit (und auch im Zusammenhang mit Docstrings) gibt es in Python eine Technik namens doctests. Verwenden Sie dies, um zu dokumentieren, wie Ihre Methoden voraussichtlich angewendet werden - und gleichzeitig eine gute Abdeckung durch Unit-Tests zu erzielen!

Daren Thomas
quelle
1
Numpy Dokumentation ist ein gutes repräsentatives Beispiel für die in der obigen Antwort angegebene Philosophie.
Musiker Putrid
5

Ja, Sie sollten docstrings verwenden, um Ihre Klassen und Funktionen für andere Programmierer benutzerfreundlicher zu gestalten:

Mehr: http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

In einigen Editoren können Sie während der Eingabe Dokumentzeichenfolgen anzeigen, was die Arbeit erheblich erleichtert.

Maciej Ziarko
quelle
+1: dokumentiere es, es ist der einzig vernünftige Weg, und das gilt auch für statisch typisierte Sprachen. Rückgabetypen machen einen unbedeutenden Teil des gesamten Bildes aus.
Detly
Ich mag meine Typen, vielen Dank. Dokumentation + Typen = Himmel
masm64
5

Ich besuchte einen Coursera-Kurs, es gab eine Lektion, in der wir über Designrezepte unterrichtet wurden.

Unterhalb des Docstring-Formats fand ich Preety nützlich.

def Bereich (Basis, Höhe):
    '' '(Nummer, Nummer) -> Nummer # ** TypeContract **
    Geben Sie den Bereich eines Trings mit der Bemaßungsbasis # ** Beschreibung ** zurück
    und Höhe

    >>> Bereich (10,5) # ** Beispiel **
    25.0
    >> Bereich (2,5,3)
    3,75
    '' '
    Rückgabe (Basis * Höhe) / 2 

Ich denke, wenn Docstrings auf diese Weise geschrieben werden, könnte dies Entwicklern sehr helfen.

Link zum Video [Sehen Sie sich das Video an] : https://www.youtube.com/watch?v=QAPg6Vb_LgI

Sumit Murari
quelle
2

Ja ist es.

In Python muss eine Funktion nicht immer eine Variable desselben Typs zurückgeben (obwohl Ihr Code besser lesbar ist, wenn Ihre Funktionen immer denselben Typ zurückgeben). Das bedeutet, dass Sie keinen einzigen Rückgabetyp für die Funktion angeben können.

Ebenso müssen die Parameter nicht immer vom gleichen Typ sein.

thomson_matt
quelle
1

Beispiel: Wie kann in einer Dokumentzeichenfolge kurz beschrieben werden, dass eine Funktion eine Liste von Tupeln mit jedem Tupel des Formulars (Knoten-ID, Knotenname, Uptime-Minuten) zurückgibt und dass die Elemente jeweils eine Zeichenfolge, eine Zeichenfolge und eine Ganzzahl sind?

Ähm ... Es gibt keine "prägnante" Beschreibung dafür. Es ist komplex. Sie haben es so konzipiert, dass es komplex ist. Und es erfordert eine komplexe Dokumentation in der Dokumentzeichenfolge.

Entschuldigung, aber Komplexität ist - na ja - komplex.

S.Lott
quelle
2
OK. Off-Topic (irgendwie): Aber was wäre dann ein saubereres Design? Klassen?
Rabarberski
@ Rabarberski: Nicht unbedingt. Komplexität klingt hier unvermeidlich. Prägnanz ist nicht immer erreichbar oder sogar wünschenswert.
S.Lott
Eine naheliegende Möglichkeit, solche Dinge zu dokumentieren, ist die Verwendung von Java-Generika wie in: list <tuple <int, str, int >>. Aber das ist nicht der Python-Weg, zum Guten oder zum Schlechten.
Skyler
0

Ja, da es sich um eine dynamisch typisierte Sprache handelt;)

Lesen Sie dies als Referenz: PEP 257

Alois Cochard
quelle
0

Docstrings (und Dokumentation im Allgemeinen). Python 3 führt (optionale) Funktionsanmerkungen ein, wie in PEP 3107 beschrieben (aber Docstrings nicht auslassen).

Steven
quelle