Wie soll ich Funktionen benennen, die in Python Werte zurückgeben?

13

Ich bin verwirrt über die Auswahl von Namen für meine Funktionen in Python . Manchmal sind in Python integrierte Funktionen unerlässlich, z. B.: printFunktion und Zeichenfolgenmethode find. Manchmal sind sie nicht so wie: Der lenName ist nicht zwingend wie calculate_lenzum Beispiel und typeist es auch nicht find_type.

Ich kann verstehen, dass printein Wert zurückgegeben wird, den wir nicht verwenden (dh None) und etwas tut (dh es wird eine Zeichenfolge auf dem Bildschirm angezeigt), daher ist sein Name unbedingt erforderlich.

Aber lengibt einen Wert , dass wir verwenden und tut etwas (dh die Berechnung , wie viele Elemente gibt es in einer Sequenz oder einer Abbildung.) Und sein Name ist nicht zwingend notwendig . Andererseits gibt die findZeichenfolgenmethode (as len) einen Wert zurück, den wir verwenden, und führt etwas aus. Der Name ist unbedingt erforderlich .

Was diese Frage gestellt hat, ist, dass ich ein Skript, das Zeichenfolgen mit Caesar-Chiffre verschlüsselt und entschlüsselt, überprüft habe. Der Rezensent sagte, dass:

Nur ein Bauchgefühl: Funktionen machen Sachen. Ein guter Name für eine Funktion ist daher ein Muss: Ich würde rotate_letterstattdessen verwenden rotated_letter.

rotated_letterGibt eine Zeichenfolge mit einem Buchstaben zurück, die einen Buchstaben darstellt, der um eine Zahl gedreht wurde. Ich weiß nicht, was besser ist, ich habe es verwendet, rotated_letterda es einen Wert zurückgibt, wie eine randintFunktion im Zufallsmodul , ist es nicht generate_randint.

Wie soll ich in diesem Fall eine Funktion benennen, die einen zu verwendenden Wert zurückgibt? Soll ich den Namen machen Imperativ oder einfach nur ein Substantiv . In anderen Fällen ist es offensichtlich, wie es geht, wie z. B. boolesche Funktionen , wie is_evenund is_palindromewir machen es einfach wie eine Ja / Nein-Frage , und auch Funktionen, die nur nicht verwendete Werte (dh None) ausführen und zurückgeben , wie z. B. eine printListenmethode sort.

Mahmood Muhammad Nageeb
quelle
Das ist eigentlich eine sehr verbreitete Praxis (ich würde sagen eine Konvention), Imperative bei der Benennung von Funktionen zu verwenden. Wie benennt man beispielsweise eine Variable, in der der gedrehte Buchstabe der Funktion rotated_letter gespeichert ist?
JoulinRouge
Das ist keine gute Art, an einige Ihrer Beispiele zu denken. lenwird beispielsweise besser als "Länge von" betrachtet - Sie erhalten eine Beschreibung des Arguments auf Metaebene.
Izkata

Antworten:

10

Verwenden Sie Verben, wo dies sinnvoll ist, Substantive, wenn sie kürzer und eindeutig sind

Meistens sollten Funktionen (imperative) Verben und Klassen sein, Variablen und Parameter sollten Substantive sein. Attribute sollten auch Substantive sein, einschließlich solcher, die mit erstellt wurden @property. Dies gilt insbesondere für Funktionen mit Nebenwirkungen. [1] Wenn eine Funktion etwas zurückgibt, sollten Sie bewerten, ob das Verb etwas hinzufügt oder nur "Rauschen" ist:

  • make_list(foo)vs list(foo).: Das Substantiv ist leichter zu lesen als das Verb. Auch listist eigentlich eine Klasse, und Klassen sollten Substantive sein.
  • open(foo)vs file(foo).: Das Verb ist leichter zu lesen als das Substantiv, und es ist sinnvoller, einem Verb "Optionen" zu geben als einem Substantiv. Daher wurde das Substantiv in Python 3 entfernt. Dies open()bleibt der einzige "Standard" [2] um Dateiobjekte in Python 3 zu erstellen.
  • foo.get_bar()vs. foo.bar()vs. foo.bar(nimm an foound barsind beide Substantive): Die erste Option ist richtig, weil das "get" nichts hinzufügt, was wir noch nicht wussten. Die zweite ist dann angebracht , wenn ein immer baraus einer foopotenziell teure Operation und / oder trägt Nebenwirkungen (Sie auch interessieren könnten , Bar(foo)wenn Bareine Klasse). Der dritte ist angemessen, wenn dies ein billiger Vorgang ohne Nebenwirkungen ist und alternative Implementierungen ihn wahrscheinlich nicht teuer machen .
  • xs.sort()vs. sorted(xs)wenn Sie xseine Liste: Die erste ist zwingend notwendig: Sortieren Sie die Liste. Es ändert die Liste an Ort und Stelle und gibt nichts zurück. Die zweite ist deklarativ: Eine Liste, die sortiert ist und genau das zurückgibt. Beide sind Verben.

[1]: Normalerweise schließen sich die Rückgabe eines Werts und Nebenwirkungen gegenseitig aus, es sei denn, Sie haben einen zwingenden Entwurfsgrund, diese zu kombinieren. Eine Funktion mit Nebenwirkungen sollte also wahrscheinlich nichts zurückgeben, und daher wäre es wenig sinnvoll, sie zu einem Substantiv zu machen.
[2]: Das ioModul enthält einige Operationen auf mäßig niedrigerer Ebene, mit denen Dateipufferung, automatische En- / Decodierung von Text usw. hinzugefügt oder entfernt werden können. Dies sind meistens Substantive, da es sich um objektorientierte Klassen handelt. Die meisten Benutzer müssen nicht direkt mit diesen Dingen spielen. open()wählt stattdessen eine geeignete Klasse aus und instanziiert sie automatisch.

Kevin
quelle
Vielen Dank! Was ist in " foo.get_bar() vs.` foo.bar ()` vs. foo.bar" der Unterschied zwischen dem zweiten und dem dritten ?
Mahmood Muhammad Nageeb
Das dritte ist entweder eine Eigenschaft oder ein nacktes Attribut. Die zweite ist eine Methode.
Kevin
Wenn ich das verstehe, ist es angemessen, keinen rotated_letterImperativ zu machen und ihn deklarativ zu halten, oder?
Mahmood Muhammad Nageeb
In diesem Fall bin ich mir nicht sicher, ob dies letterdurch den Kontext impliziert wird.
Kevin
+1 für die Erwähnung listist eine Klasse
Dušan Maďar
0

rotated_lettersieht nicht nach einer Methode aus. Es sieht aus wie eine Immobilie. Was bedeutet, dass die erste Idee ist:

var letter = caesar.rotated_letter

Erwarten letter, einen Wert vom Typ string zu enthalten, keine Funktion. Von dort aus haben Sie entweder einen anderen Namen gewählt, z.

def rotate_letter(self):
    pass

oder Sie verwenden stattdessen eine Eigenschaft:

@property
def rotated_letter(self):
    return self.whatever

lenund typewerden so benannt, weil jeder andere Name lang zu tippen wäre. Sie werden häufig verwendet und haben einen besonderen Status der Python-Kernfunktionen, den jeder Python-Programmierer ohnehin erlernen wird, wodurch ihre Namen viel irrelevanter sind als die Namen von Bibliotheken von Drittanbietern.

lenDies ist insbesondere ein gutes Beispiel dafür, was Sie in Ihrem Code nicht tun sollten : Es wird erwartet, dass Sie vollständige Namen wie length(es sei denn, die Kurzform ist sehr beliebt, wie z. B. max) und ein Verb wie z compute_length. Oder es könnte eine Eigenschaft sein: len([1, 5, 6])wird [1, 5, 6].length. In C # wird beispielsweise die spätere Form verwendet : new [] { ... }.Length.

Beachten Sie, dass es auch historische Gründe geben kann für len: andere Sprachen, wie z. B. C #, bevorzugt Count, was normalerweise eine Methode ist (obwohl das Verhalten durch .NET Framework leider inkonsistent ist). Countist ein Verb, so intuitiv, dass Sie dazu neigen, es als Methode aufzurufen.

Werte zurückgeben oder eine Aktion ausführen

Von einer Funktion wird immer erwartet, dass sie eine Aktion ausführt. Wenn es kaum einen Wert zurückgibt, sollte es eine Eigenschaft sein. Sie haben einen Hinweis, dass die Funktion in eine Eigenschaft umgewandelt werden sollte, wenn:

  • Die Funktion enthält kaum eine return ...Anweisung,

  • Der Name der Funktion, der Ihnen natürlich in den Sinn kommt get_something, lautet wie in product.get_price().

Wenn Sie eine Funktion haben, kann dies einer von vier Typen sein:

  • Es kann rein sein, dh einen Wert zurückgeben, ohne die Umgebung zu beeinträchtigen. Beispiel : road.measure_distance().

  • Es kann die Umwelt beeinträchtigen, ohne etwas zurückzugeben. Beispiel : product_database.remove_record(1234).

  • Dies kann sich auf die Umgebung auswirken und einen Wert zurückgeben. Beispiel: value.increment()verwendet wie value++.

  • Es kann nichts tun und nichts zurückgeben. Beispiel : time.sleep(1).

Es gibt nur wenige Fälle, in denen der Name einen starken Hinweis auf den Typ der Funktion geben könnte, aber in vielen Fällen können Sie den Typ kaum anhand seines Namens erkennen.

Arseni Mourzenko
quelle
Ich nehme an, die Antwort lautet "Ja", aber ich muss fragen: Antworten Sie vollständig aus der Perspektive von Python? Weil in anderen Sprachen Ihre Trennung von Funktion und Eigentum nicht immer wahr ist; Es ist auch nicht wahr, dass eine Funktion "eine Aktion ausführen muss". Ist das die Konvention in Python? (Ich schreibe Python, habe aber nicht alle PEPs gelesen und bin definitiv kein Experte. Ich habe nicht abgelehnt, übrigens).
Andres F.
@AndresF.: Ich antworte aus der Perspektive von Python. In Sprachen wie Java, in denen keine Eigenschaften vorhanden sind getSomethingund setSomethingdie üblichen Namen anstelle von Eigenschaften verwendet werden.
Arseni Mourzenko