Ich dachte, einer der Eckpfeiler von OOP ist, dass wir Objekte haben, mit denen wir uns befassen möchten, und dann senden wir ihnen Nachrichten.
Es mag also natürlich erscheinen, dass ich eine Sammlung von Gegenständen habe und sie in eine Zeichenfolge einfügen muss, um dies zu tun:
["x", "o", "o"].join(" | ") # joining a tic-tac-toe row in Ruby
(Smalltalk macht es genauso). Das " | "
ist in gewisser Weise ein Argument, ein Zeichen dafür, wie man sich ihm anschließt. Es kann auch sein " "
, wenn das Spielbrett einfacher sein soll. Das Verbindungselement " | "
ist also nicht besonders etwas, an dem wir interessiert sind - es sind nicht die Hauptobjekte im Programm, die eine besondere Bedeutung oder Bedeutung haben.
Wenn Python es mit macht
" | ".join(["x", "o", "o"])
Es fühlt sich etwas seltsam an, dass es sich fast so anfühlt, als würden wir eine Nachricht an das Argument weitergeben, um das Argument über etwas zu erzählen. Vielleicht ist Python prozeduraler? Um der Verbindungskette zu sagen, dass sie eine Pflicht für uns erfüllen soll?
Soll die Implementierung gespeichert werden, damit wir nicht join
für jede vorhandene Auflistungsklasse eine definieren müssen? Aber stimmt es nicht, dass wir auch nur einmal für eine Sammlungsklasse schreiben können, wie in Ruby:
module Enumerable
def my_join(joiner)
self.inject {|a,b| a.to_s + joiner + b.to_s}
end
end
(so etwas, to_s
jedes Element aufrufen , sich darauf verlassen, dass to_s
jede Klasse ihre eigene Sache macht, in eine Zeichenfolge konvertiert und sie dann verkettet). Dann müssen wir nicht für jeden String, Hash oder Set oder für jede Auflistungsklasse, die wir haben, implementieren.
Oder geht Python nicht richtig die OOP-Route? Es verwendet len("abc")
und type([])
anstelle "abc".len()
oder [].type()
sogar in Python3 scheint es auch. Tut Python dies aus Designgründen so?
quelle
Maybe Python is more procedural?
Python war eine prozedurale Sprache mit einigen funktionalen Ergänzungen ("Python hat Lambda, Reduce (), Filter () und Map () erworben, mit freundlicher Genehmigung eines Lisp-Hackers, der sie verpasst und funktionierende Patches eingereicht hat"), bis etwas in der Version zu sein scheint 2. Das war ungefähr anderthalb Jahrzehnte nach der ersten Bearbeitung.Antworten:
Pythons Join ist so konzipiert, dass er mit jedem iterierbaren Element funktioniert . Dies bedeutet, dass die Designer entscheiden mussten, wo sie es platzieren möchten. Da es auf mehr als nur Listen funktioniert, aber immer erfordert (Separator) und liefert einen String, beschlossen sie , sie geben Sie einen Teil des Strings zu machen.
Armin Ronacher sagt es besser als ich:
http://lucumr.pocoo.org/2011/7/9/python-and-pola/#seemingly-inverse-logic
quelle
module Enumerate
Abschnitt zu beheben, aber Python funktioniert nicht so. Es gibt keine einzige Oberklasse für alle Iteratoren, in die Sie diese Methode einfügen könnten.Hash
und habeString
eigentlich keine Sammlungsklasse als Oberklasse ... ihre Oberklasse ist gerechtObject
. Diese beiden Klassen verlassen sich also nur auf das Enumerable-Mixin ... etwas, wie ich es verstehe, wie eine Schnittstelle, um die Verhaltensweisen einer Sammlung zu