La combinación de Python parece centrarse no en los elementos a unir, sino en el símbolo, en comparación con Ruby o Smalltalk, por una razón de diseño.

9

Pensé que una de las piedras angulares de OOP es que tenemos objetos, que son los elementos con los que estamos interesados ​​en tratar, y luego les enviamos mensajes.

Por lo tanto, puede parecer natural que tenga una colección de artículos, y necesito ponerlos en una cadena, para hacerlo:

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

(Smalltalk lo hace de la misma manera). De " | "alguna manera, se considera como un argumento, una muestra de cómo unirse a él. También puede serlo " ", si el tablero de juego es más simple. Por lo tanto, el elemento de unión " | "no es particularmente algo en lo que tengamos interés, no son los objetos principales del programa los que tienen una importancia o significado particular.

Si Python lo hace usando

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

Se siente algo extraño que casi parece que estamos pasando un mensaje al argumento, para decirle al argumento sobre algo. ¿Quizás Python es más procesal? ¿Decirle a la cadena de unión que realice algún deber para nosotros?

¿Es para guardar la implementación, de modo que no tengamos que definir un joinpara cada clase de colección que tenemos? Pero, ¿no es cierto que también podemos escribir una vez para cualquier clase de colección, como en Ruby:

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

(algo como esto, recurriendo to_sa cada elemento, confiando en que to_scada clase haga lo propio, convertirlo en una cadena y luego concatenarlos). Entonces no tenemos que implementar para cada String, Hash o Set, o cualquier clase de colección que tengamos.

¿O Python sale bien y no sigue la ruta OOP? Utiliza len("abc")y en type([])lugar de "abc".len()o [].type()incluso en Python3 también parece. ¿Python lo hace de esta manera por una razón de diseño?

nonopolaridad
fuente
77
De The Zen of Python : "Debería haber una, y preferiblemente solo una, forma obvia de hacerlo. Aunque esa forma puede no ser obvia al principio a menos que seas holandés".
kdgregory
2
En una forma, la colección sabe cómo convertirse en una cadena con un delimitador, en la otra, una cadena sabe cómo concatenar una colección usando a sí misma como delimitador. Ambos están orientados a objetos, pero cambian el sujeto y el objeto del verbo.
kdgregory
Maybe Python is more procedural?Python era un lenguaje de procedimiento con algunas adiciones funcionales ("Python adquirió lambda, reduce (), filter () y map (), cortesía de un hacker de Lisp que los perdió y envió parches de trabajo") hasta que parece estar en algún lugar de la versión 2. Eso fue aproximadamente una década y media después de que se trabajó por primera vez.
1
E incluso hoy Python ni siquiera está tratando de ser un lenguaje OOP, es completamente multi-paradigma.
Al igual que C ++, Python es un lenguaje que permite POO. Esto no es lo mismo que un lenguaje OOP como Java o Smalltalk.
Gort the Robot

Respuestas:

9

La combinación de Python está diseñada para funcionar en cualquier iterable . Esto significa que los diseñadores tuvieron que decidir dónde colocarlo. Como funciona en más que solo listas, pero siempre requiere (separador) y devuelve una cadena, decidieron hacerla parte del tipo de cadena.

Armin Ronacher lo dice mejor que yo:

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

"Imagine que Python no funcionaría de esa manera. Primero tendría que convertir el iterable en una lista real para convertirlo en una cadena. La gente de Ruby ahora argumentará que Ruby resuelve este problema al mezclar módulos, y ciertamente están en lo cierto. es una opción. Pero esta es una decisión de diseño consciente en el lenguaje que tiene muchas implicaciones. Python fomenta el acoplamiento flexible al tener estos protocolos donde las implementaciones reales pueden estar en otro lugar. Un objeto es iterable, otra parte del sistema sabe cómo hacerlo en una cuerda ".

Roger escaso
fuente
1
OP intenta abordar esto con la module Enumeratesección, pero Python no funciona de esa manera, no hay una superclase única para todos los iteradores donde podría colocar este método.
También probé en Ruby 2.0 ... Hashy en Stringrealidad no tengo una clase de colección como superclase ... su superclase es justa Object. Entonces, estas dos clases solo confían en tener el Enumerable mixin ... algo que entiendo como una interfaz para permitir el conjunto de comportamientos de una colección
polaridad
Entonces, ¿es más o menos una limitación del hecho de que "iterable" no es una clase o algo con código real, sino más bien un patrón de escritura de pato? Alternativamente, es simplemente porque Python quería ser tan general como para poder trabajar en cualquier colección con la misma implementación (mientras que muchas otras bibliotecas estándar simplemente lo implementarían para cada colección si realmente se aplica a esa colección).
Kat