Wann sollte ich in Python eine Funktion anstelle einer Methode verwenden?

Den Zen of Python hinweist, dass es sollte nur eine Möglichkeit sein, Dinge zu tun - doch Häufig hatte ich das problem zu entscheiden, wenn Sie eine Funktion verwenden, versus, wenn eine Methode zu verwenden.

Nehmen wir mal ein triviales Beispiel - ein Schachbrett-Objekt. Sagen wir, wir müssen einige Weg, um alle rechtlichen König bewegt sich auf das Brett. Wir schreiben Schachbrett.get_king_moves() oder get_king_moves(chess_board)?

Hier sind einige Fragen, die ich angeschaut:

Die Antworten, die ich bekam, waren weitgehend ergebnislos:

Warum Python-Methoden benutzen, um einige Funktionen (z.B. Liste.index()) funktioniert aber auch für andere (z.B. len(Liste))?

Ist das der Hauptgrund dafür ist die Geschichte. Funktionen verwendet wurden für diese Operationen, die generisch für eine Gruppe von Arten und die waren
sollte die Arbeit auch für Objekte, die nicht über Methoden auf allen
(z.B. Tupel). Es ist auch praktisch, um eine Funktion haben kann
leicht angewendet werden, um eine amorphe Sammlung von Objekten, wenn Sie verwenden
die funktionellen Eigenschaften von Python (Karte(), apply() et al.).

In der Tat, die Umsetzung der len(), max(), min() als built-in-Funktion ist tatsächlich weniger code als die Umsetzung als Methoden für jeden Typ.
Man kann Haarspalterei über einzelne Fälle, sondern es ist ein Teil von Python und
es ist zu spät, um derart grundlegende Veränderungen, die jetzt. Die Funktionen haben
zu bleiben, zu vermeiden, riesige code Bruch.

Während interessant, die oben nicht wirklich viel sagen, welche Strategie zu verabschieden.

Dies ist einer der Gründe - mit benutzerdefinierten Methoden, die Entwickler wäre
frei zu wählen, eine andere Methode name, wie getLength(), length(),
getlength() oder was auch immer. Python erzwingt strenge benennen, so dass die
gemeinsame Funktion len() kann verwendet werden.

Etwas interessanter. Mein nehmen ist, dass die Funktionen werden in einem Sinn, der Pythonic version von Schnittstellen.

Schließlich von Guido selbst:

Reden über die Fähigkeiten/Schnittstellen hat mich zum nachdenken über einige unserer
"rogue" spezielle Methode Namen. In der Sprachreferenz, es sagt, "Ein
Klasse umsetzen können bestimmte Operationen, die aufgerufen werden, indem spezielle
syntax (wie z.B. arithmetische Operationen oder subscripting und schneiden) von
die Definition von Methoden mit speziellen Namen." Aber es gibt alle diese Methoden, die
mit speziellen Namen wie __len__ oder __unicode__ die zu sein scheinen
zur Verfügung gestellt für den nutzen von eingebauten Funktionen, als zum
Unterstützung der syntax. Vermutlich in einer interface-basierten Python, diese
Methoden erweisen würden, in regelmäßigen Abständen, benannten Methoden, die auf einer ABC, so dass
__len__ werden würde

class container:
  ...
  def len(self):
    raise NotImplemented

Obwohl, denken Sie darüber etwas mehr, ich sehe nicht ein, warum alle syntaktische
Operationen würden nicht nur aufrufen, die entsprechende Regel-Methode mit dem Namen
auf eine bestimmte ABC. "<", zum Beispiel, würde vermutlich aufrufen
"object.lessthan" (oder vielleicht "comparable.lessthan"). Also eine andere
Vorteil wäre die Fähigkeit zu entwöhnen Python-Weg von diesem
mangled-name Ungereimtheit, und das scheint mir ein HCI-Verbesserung
.

Hm. Ich bin mir nicht sicher, ob ich einverstanden (Abbildung aus :-).

Gibt es zwei Teile von "Python Begründung" das würde ich gerne erklären
erste.

Erste von allen, die ich wählte, len(x) über x.len() für die HCI Gründen (def
__len__()
kam erst viel später). Es sind zwei Ineinander verschlungenen Gründen eigentlich beide HCI:

(a) Für einige Operationen, die Präfix-notation, nur liest sich besser als
postfix -- prefix (und infix!) Operationen haben eine lange tradition in der
Mathematik, die mag Notationen, wo die visuals helfen, die
Mathematiker denken über ein problem. Vergleichen Sie das einfach mit, die wir
umschreiben einer Formel, wie x*(a+b) in x*a + x*b auf die Ungeschicklichkeit des
tun die gleiche Sache mit einem raw-OO-notation.

(b), Wenn ich Lesen Sie code, der sagt len(x) ich wissendass es zu Fragen für
die Länge von etwas. Das sagt mir zwei Dinge: das Ergebnis ist ein
integer, und das argument ist eine Art von container. Im Gegenteil,
wenn ich lese x.len(), ich muss schon wissen, dass x ist eine Art von
container-Implementierung einer Schnittstelle oder Erben von einer Klasse, die
hat eine standard -len(). Zeugen der Verwirrung, die wir gelegentlich haben, wenn
eine Klasse, die nicht die Implementierung eines mapping hat eine get() oder keys()
Methode, oder etwas, das nicht eine Datei hat eine write() Methode.

Sagen, die gleiche Sache in einer anderen Weise, ich seh 'len' als built-in
Betrieb. Ich würde es hassen, zu verlieren. Ich kann nicht sicher sagen, ob man gemeint ist oder nicht, aber 'def len(self): ...' klingt wie Sie
möchten herabstufen es um eine gewöhnliche Methode. Ich bin stark -1.

Das zweite bit von Python Begründung, die ich versprochen zu erklären, ist nicht der Grund
warum entschied ich mich für die speziellen Methoden zu suchen __special__ und nicht nur
special. Ich war Antizipation viele Operationen, die Klassen könnten wollen
zu überschreiben, einige Standards (z.B. __add__ oder __getitem__), manche nicht so
standard (z.B. Gurke ist __reduce__ für eine lange Zeit hatte keine Unterstützung in C
code). Ich wollte nicht, dass diese speziellen Operationen zu verwenden gewöhnlichen
Methodennamen, weil dann bereits vorhandenen Klassen oder Klassen die schriftliche durch
Benutzer ohne ein enzyklopädisches Gedächtnis für alle speziellen Methoden,
haftet versehentlich Vorgänge zu definieren, die Sie nicht bedeuten, zu
implementieren, mit möglicherweise katastrophalen Folgen. Ivan Krstić
das erklärt mehr prägnant in seiner Botschaft, die ankam, nachdem ich
dies alles geschrieben.

--
--Guido van Rossum (Homepage: http://www.python.org/~guido/)

Mein Verständnis davon ist, dass in bestimmten Fällen, die Präfix-notation macht einfach mehr Sinn (ie, Ente.quack macht mehr Sinn als quack(Ente) aus linguistischer Sicht.) und wieder werden die Funktionen "Schnittstellen".

In diesem Fall, meine Vermutung wäre die Umsetzung get_king_moves ausschließlich auf Basis der Guido ist der erste Punkt. Aber das lässt immer noch eine Menge offene Fragen zu sagen, die Implementierung einer stack-und queue-Klasse mit ähnlichen push und pop Methoden - sollten diese Funktionen oder Methoden? (hier würde ich vermuten-Funktionen, weil ich wirklich wollen, um zu signalisieren push-pop-Schnittstelle)

TLDR: Kann jemand erklären, was die Strategie für die Entscheidung, Wann Funktionen vs. Methoden sollten?

InformationsquelleAutor der Frage Ceasar Bautista | 2011-11-13

Schreibe einen Kommentar