Gabung Python tampaknya tidak berfokus pada item untuk bergabung, tetapi pada simbol, dibandingkan dengan Ruby atau Smalltalk, karena alasan desain?

9

Saya pikir salah satu landasan OOP adalah bahwa, kami memiliki objek, yang merupakan item yang kami minati, dan kemudian kami mengirim pesan kepada mereka.

Jadi mungkin tampak alami bahwa, saya memiliki koleksi barang, dan saya perlu memasukkannya ke dalam satu string, jadi untuk melakukannya:

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

(Smalltalk melakukannya dengan cara yang sama). Dalam " | "beberapa hal dianggap sebagai argumen, salah satu cara untuk bergabung. Bisa " "juga, jika papan permainan lebih sederhana. Jadi elemen yang bergabung " | "bukanlah sesuatu yang kita minati - itu bukan objek utama dalam program yang memiliki kepentingan atau signifikansi tertentu.

Jika Python menggunakannya

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

Rasanya agak aneh bahwa hampir rasanya seperti kami menyampaikan pesan ke argumen, untuk mengatakan argumen tentang sesuatu. Mungkin Python lebih prosedural? Untuk memberitahu string yang bergabung untuk melakukan tugas bagi kita?

Apakah ini untuk menyelamatkan implementasi, sehingga kita tidak perlu mendefinisikan a joinuntuk setiap kelas koleksi yang kita miliki? Tapi bukankah benar bahwa kita juga bisa menulis sekali saja untuk kelas koleksi apa saja, seperti di Ruby:

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

(sesuatu seperti ini, memanggil to_ssetiap item, mengandalkan to_smasing-masing kelas untuk melakukan hal yang benar, untuk mengkonversi ke string, dan kemudian menyatukan mereka). Jadi kita tidak perlu mengimplementasikan untuk setiap String, Hash, atau Set, atau kelas koleksi apa pun yang kita miliki.

Atau apakah Python yang benar tidak menuju rute OOP? Ini menggunakan len("abc")dan type([])bukannya "abc".len()atau [].type()bahkan di Python3 juga tampaknya. Apakah Python melakukannya dengan alasan desain?

nonopolaritas
sumber
7
Dari The Zen of Python : "Seharusnya ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya. Meskipun cara itu mungkin tidak jelas pada awalnya kecuali Anda orang Belanda."
kdgregory
2
Dalam satu bentuk, koleksi tahu bagaimana mengubah dirinya menjadi string dengan pembatas, di lain string tahu bagaimana menggabungkan koleksi menggunakan dirinya sebagai pembatas. Keduanya berorientasi objek, tetapi mengubah subjek dan objek kata kerja.
kdgregory
Maybe Python is more procedural?Python adalah bahasa prosedural dengan beberapa penambahan fungsional ("Python mengakuisisi lambda, mengurangi (), filter () dan map (), milik seorang hacker Lisp yang melewatkannya dan mengirimkan tambalan yang berfungsi") sampai apa yang tampak di suatu tempat dalam versi 2. Itu sekitar satu dekade setengah setelah pertama kali dikerjakan.
1
Dan bahkan hari ini Python bahkan tidak berusaha untuk menjadi bahasa OOP, itu sepenuhnya multi-paradigma.
Seperti C ++, Python adalah bahasa yang memungkinkan OOP. Ini tidak sama dengan bahasa OOP seperti Java atau Smalltalk.
Gort the Robot

Jawaban:

9

Gabung Python dirancang untuk bekerja pada setiap iterable . Ini berarti para desainer harus memutuskan di mana harus meletakkannya. Karena berfungsi lebih dari sekadar daftar, tetapi selalu membutuhkan (pemisah) dan mengembalikan string, mereka memutuskan untuk menjadikannya bagian dari tipe string.

Armin Ronacher mengatakan itu lebih baik daripada saya:

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

"Bayangkan Python tidak akan bekerja seperti itu. Anda harus mengubah iterable menjadi daftar yang sebenarnya terlebih dahulu untuk mengubahnya menjadi string. Orang-orang Ruby sekarang akan berpendapat bahwa Ruby menyelesaikan masalah ini dengan mencampur dalam modul, dan mereka tentu benar bahwa ini adalah sebuah pilihan.Tapi ini adalah keputusan desain yang disengaja dalam bahasa yang memiliki banyak implikasi.Python mendorong kopling longgar dengan memiliki protokol ini di mana implementasi yang sebenarnya bisa di tempat lain.Satu objek dapat diubah, bagian lain dalam sistem tahu bagaimana membuatnya menjadi string. "

Hanya sedikit Roger
sumber
1
OP semacam mencoba mengatasi ini dengan module Enumeratebagian tetapi Python tidak bekerja seperti itu, tidak ada superclass tunggal untuk semua iterator di mana Anda bisa meletakkan metode ini.
Saya mencoba di Ruby 2.0 juga ... Hashdan Stringsebenarnya tidak memiliki kelas koleksi sebagai superclass ... hanya superclass mereka Object. Jadi dua kelas ini hanya mengandalkan memiliki Enumerable mixin ... sesuatu yang saya mengerti seperti antarmuka untuk memungkinkan serangkaian perilaku koleksi
nonopolaritas
Jadi itu adalah batasan fakta bahwa "iterable" bukan kelas atau sesuatu dengan kode yang sebenarnya, melainkan pola mengetik bebek? Atau, itu hanya karena Python ingin menjadi begitu umum untuk dapat bekerja pada koleksi apa pun dengan implementasi yang sama (sedangkan banyak perpustakaan standar lainnya hanya akan mengimplementasikannya untuk setiap koleksi jika itu benar-benar berlaku untuk koleksi itu).
Kat