Il join di Python sembra non concentrarsi sugli elementi da unire, ma sul simbolo, rispetto a Ruby o Smalltalk, per un motivo di progettazione?

9

Ho pensato che una delle pietre miliari di OOP è che abbiamo oggetti, che sono gli oggetti a cui siamo interessati e che quindi inviamo loro messaggi.

Quindi può sembrare naturale che io abbia una collezione di oggetti, e ho bisogno di metterli in una stringa, quindi per farlo:

  ["x", "o", "o"].join(" | ")    # joining a tic-tac-toe row in Ruby

(Smalltalk lo fa allo stesso modo). Il " | " è in qualche modo pensato come argomento, un token di come unirlo. Può anche essere " " , se il tabellone deve essere più semplice. Quindi l'elemento di unione " | " non è particolarmente qualcosa a cui abbiamo interesse - non sono gli oggetti principali del programma che hanno un'importanza o un significato particolare.

Se Python lo usa usando

  " | ".join(["x", "o", "o"])

Sembra un po 'strano che ci si senta quasi come se stessimo passando un messaggio alla discussione, per dire la discussione su qualcosa. Forse Python è più procedurale? Per dire alla stringa di unione di eseguire qualche dovere per noi?

È per salvare l'implementazione, in modo da non dover definire un join per ogni classe di raccolta che abbiamo? Ma non è vero che possiamo anche scrivere una sola volta per qualsiasi classe di raccolta, come in Ruby:

module Enumerable
  def my_join(joiner)
    self.inject {|a,b| a.to_s + joiner + b.to_s}
  end
end

(qualcosa di simile a questo, chiamando to_s su ogni elemento, facendo affidamento sul to_s di ogni classe per fare la propria cosa, per convertire in una stringa e quindi concatenarli). Quindi, non dobbiamo implementare per ogni stringa, hash o set o qualsiasi altra classe di raccolta che abbiamo.

O Python ha ragione, non segue la rotta OOP? Usa len("abc") e type([]) invece di "abc".len() o [].type() anche in Python3 sembra. Python lo fa in questo modo per un motivo di progettazione?

    
posta 太極者無極而生 27.12.2015 - 18:41
fonte

1 risposta

9

Il di Python è progettato per funzionare su qualsiasi //wiki.python.org/moin/Iterator">iterable. Ciò significa che i progettisti dovevano decidere dove metterlo. Dato che funziona su più di un semplice elenco, ma sempre richiede (separatore) e restituisce una stringa, hanno deciso di renderlo parte del tipo di stringa.

Armin Ronacher lo dice meglio di me:

link

"Imagine Python would not work that way. You would have to convert the iterable into an actual list first to convert it into a string. Ruby people will now argue that Ruby solves this problem with mixing in modules, and they are certainly correct that this is an option. But this is a concious design decision in the language which has many implications. Python encourages loose coupling by having these protocols where the actual implementations can be elsewhere. One object is iterable, another part in the system knows how to make it into a string."

    
risposta data 27.12.2015 - 22:19
fonte

Leggi altre domande sui tag