A junção de Python parece focar não nos itens a serem ingressados, mas no símbolo, em comparação com Ruby ou Smalltalk, por uma razão de design?


9

Eu pensei que uma das pedras angulares do OOP é que, temos objetos, que são os itens com os quais estamos interessados ​​em lidar, e então enviamos mensagens para eles.

Portanto, pode parecer natural que eu tenha uma coleção de itens e precise colocá-los em uma única sequência, para fazê-lo:

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

(Smalltalk faz da mesma maneira). De " | "alguma forma, é considerado um argumento, um sinal de como se juntar a ele. Pode ser " "também, se o tabuleiro do jogo for mais simples. Portanto, o elemento de junção " | "não é particularmente algo em que temos interesse - não são os principais objetos do programa que têm importância ou significado particular.

Se o Python fizer isso usando

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

Parece um pouco estranho que quase pareça que estamos passando uma mensagem para o argumento, para contar o argumento sobre algo. Talvez o Python seja mais processual? Para dizer à cadeia de junção para realizar algum dever para nós?

É para salvar a implementação, para que não tenhamos que definir um joinpara cada classe de coleção que temos? Mas não é verdade que também podemos escrever apenas uma vez para qualquer classe de coleção, como no Ruby:

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

(algo assim, chamando to_scada item, confiando no que to_scada classe faz para fazer suas próprias coisas, para converter em uma sequência e concatená-las). Portanto, não precisamos implementar para cada String, Hash ou Set, ou qualquer classe de coleção que tenhamos.

Ou o Python certo não segue a rota OOP? Ele usa len("abc")e, em type([])vez de "abc".len()ou [].type()mesmo em Python3, também parece. O Python faz dessa maneira por um motivo de design?


7
Do Zen de Python : "Deve haver uma - e preferencialmente apenas uma - maneira óbvia de fazer isso. Embora esse caminho possa não ser óbvio a princípio, a menos que você seja holandês".
Kdgregory

2
Em uma forma, a coleção sabe como se converter em uma sequência com um delimitador, no outro, uma sequência sabe como concatenar uma coleção usando-se como um delimitador. Ambos são orientados a objetos, mas mudam o assunto e o objeto do verbo.
Kdgregory

Maybe Python is more procedural?Python era uma linguagem processual com algumas adições funcionais ("Python adquiriu lambda, reduza (), filtra () e mapa (), cortesia de um hacker Lisp que as perdeu e enviou correções de trabalho") até o que parece estar em algum lugar na versão 2. Isso foi cerca de uma década e meia após o primeiro trabalho.

11
E ainda hoje o Python nem está tentando ser uma linguagem OOP, é completamente multiparadigma.

Como o C ++, o Python é uma linguagem que permite OOP. Isso não é o mesmo que uma linguagem OOP como Java ou Smalltalk.
Gort the Robot

Respostas:


9

A junção do Python foi projetada para funcionar em qualquer iterável . Isso significa que os designers tiveram que decidir onde colocá-lo. Como funciona em mais do que apenas listas, mas sempre requer (separador) e retorna uma sequência, eles decidiram fazer parte do tipo de sequência.

Armin Ronacher diz isso melhor do que eu:

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

"Imagine que o Python não funcionaria dessa maneira. Você precisaria converter o iterável em uma lista real primeiro para convertê-lo em uma string. O pessoal do Ruby agora argumentará que o Ruby resolve esse problema com a mistura de módulos, e eles certamente estão corretos. é uma opção. Mas esta é uma decisão de projeto concisa na linguagem que tem muitas implicações. O Python incentiva o acoplamento frouxo por ter esses protocolos em que as implementações reais podem estar em outro lugar. Um objeto é iterável, outra parte do sistema sabe como fazê-lo. em uma string ".


11
O OP tenta resolver isso com a module Enumerateseção, mas o Python não funciona dessa maneira, não existe uma superclasse para todos os iteradores em que você pode colocar esse método.

Também tentei no Ruby 2.0 ... Hashe Stringna verdade não tenho uma classe de coleção como superclasse ... a superclasse deles é justa Object. Então, essas duas classes confiar apenas em ter o mixin Enumerable ... algo que eu entendo como uma interface para permitir o conjunto de comportamentos de uma coleção
nonopolarity

Portanto, é praticamente uma limitação do fato de que "iterável" não é uma classe ou algo com código real, mas um padrão de digitação de pato? Como alternativa, é simplesmente porque o Python queria ser tão geral para poder trabalhar em qualquer coleção com a mesma implementação (enquanto muitas outras bibliotecas padrão apenas o implementariam para cada coleção se ela realmente se aplicar a essa coleção).
Kat
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.