La jointure de Python semble se concentrer non pas sur les éléments à joindre, mais sur le symbole, par rapport à Ruby ou Smalltalk, pour une raison de conception?

9

Je pensais que l'une des pierres angulaires de la POO est que nous avons des objets, qui sont les éléments qui nous intéressent, puis nous leur envoyons des messages.

Il peut donc sembler naturel que, j'ai une collection d'articles, et je dois les mettre dans une chaîne, donc pour le faire:

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

(Smalltalk le fait de la même manière). Le " | "est en quelque sorte considéré comme un argument, un gage de la façon de le rejoindre. Il peut en être de " "même si le plateau de jeu doit être plus simple. Donc, l'élément de jonction " | "n'est pas particulièrement quelque chose qui nous intéresse - ce ne sont pas les principaux objets du programme qui ont une importance ou une signification particulière.

Si Python le fait en utilisant

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

Cela semble un peu étrange d'avoir l'impression que nous transmettons un message à l'argument, pour raconter l'argument à propos de quelque chose. Peut-être que Python est plus procédural? Pour dire à la chaîne de jonction d'effectuer une tâche pour nous?

Est-ce pour sauver l'implémentation, afin que nous n'ayons pas à définir un joinpour chaque classe de collection que nous avons? Mais n'est-il pas vrai que nous pouvons également écrire une seule fois pour n'importe quelle classe de collection, comme dans Ruby:

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

(quelque chose comme ça, appeler to_schaque élément, s'appuyer sur le to_sde chaque classe pour faire sa propre chose, pour convertir en une chaîne, puis les concaténer). Nous n'avons donc pas à implémenter pour chacun des String, Hash ou Set, ou quelle que soit la classe de collection que nous avons.

Ou est-ce que Python ne suit pas la route OOP? Il utilise len("abc")et type([])au lieu de "abc".len()ou [].type()même en Python3 aussi il semble. Python le fait-il de cette façon pour une raison de conception?

non-polarité
la source
7
Extrait du Zen of Python : "Il devrait y avoir une - et de préférence une seule - manière évidente de le faire.
kdgregory
2
Dans une forme, la collection sait se convertir en chaîne avec un délimiteur, dans l'autre une chaîne sait comment concaténer une collection en se servant elle-même comme délimiteur. Ils sont tous deux orientés objet, mais changent le sujet et l'objet du verbe.
kdgregory
Maybe Python is more procedural?Python était un langage procédural avec quelques ajouts fonctionnels ("Python a acquis lambda, Reduce (), filter () et map (), gracieuseté d'un pirate Lisp qui les a manqués et a soumis des correctifs de travail") jusqu'à ce que ce qui semble être quelque part dans la version 2. C'était environ une décennie et demie après son premier travail.
1
Et même aujourd'hui, Python n'essaie même pas d'être un langage OOP, c'est complètement multi-paradigme.
Comme C ++, Python est un langage qui permet la POO. Ce n'est pas la même chose qu'un langage POO comme Java ou Smalltalk.
Gort the Robot

Réponses:

9

La jointure de Python est conçue pour fonctionner sur n'importe quel itérable . Cela signifie que les concepteurs ont dû décider où le mettre. Puisqu'il fonctionne sur plus que de simples listes, mais nécessite toujours (séparateur) et renvoie une chaîne, ils ont décidé de l'intégrer au type de chaîne.

Armin Ronacher le dit mieux que moi:

http://lucumr.pocoo.org/2011/7/7/9/python-and-pola/#seemingly-inverse-logic

"Imaginez que Python ne fonctionnerait pas de cette façon. Vous devez d'abord convertir l'itérable en une liste réelle pour le convertir en chaîne. Les gens de Ruby soutiendront maintenant que Ruby résout ce problème en mélangeant des modules, et ils ont certainement raison que cela est une option. Mais c'est une décision de conception concise dans le langage qui a de nombreuses implications. Python encourage un couplage lâche en ayant ces protocoles où les implémentations réelles peuvent être ailleurs. Un objet est itérable, une autre partie du système sait comment le faire dans une chaîne. "

Scant Roger
la source
1
OP essaie en quelque sorte de résoudre ce problème avec la module Enumeratesection, mais Python ne fonctionne pas de cette façon, il n'y a pas de superclasse unique pour tous les itérateurs où vous pouvez placer cette méthode.
J'ai aussi essayé dans Ruby 2.0 ... Hashet en Stringfait je n'ai pas de classe de collection en tant que superclasse ... leur superclasse est juste Object. Donc, ces deux classes reposent simplement sur le mixage Enumerable ... quelque chose que je comprends comme une interface pour permettre l'ensemble des comportements d'une collection
non
C'est donc à peu près une limitation du fait que "itérable" n'est pas une classe ou quelque chose avec du code réel, mais plutôt un modèle de frappe de canard? Alternativement, c'est simplement parce que Python voulait être assez général pour pouvoir travailler sur n'importe quelle collection avec la même implémentation (alors que de nombreuses autres bibliothèques standard l'implémenteraient simplement pour chaque collection si elle s'applique réellement à cette collection).
Kat