Здається, приєднання Python орієнтоване не на елементи, які потрібно приєднати, а на символ, порівняно з Ruby або Smalltalk, з причини дизайну?


9

Я подумав, що одним із наріжних каменів ООП є те, що у нас є об'єкти, які є предметами, з якими ми зацікавлені мати справу, а потім ми надсилаємо їм повідомлення.

Тож може здатися природним, що у мене є колекція елементів, і мені потрібно скласти їх в один рядок, щоб це зробити:

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

(Smalltalk робить це так само). Це " | "певним чином розглядається як аргумент, один знак того, як до нього приєднатися. Це може бути " "занадто, якщо ігрова дошка буде простішою. Таким чином, елемент, що приєднується " | ", не особливо те, що нас цікавить - це не головні об'єкти програми, які мають особливе значення чи значення.

Якщо Python робить це за допомогою

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

Дуже дивно, що майже відчуваєш, що ми передаємо аргумент, щоб розповісти аргумент про щось. Можливо, Python є більш процедурним? Щоб сказати приєднувальному рядку виконувати якийсь обов'язок перед нами?

Чи потрібно зберегти реалізацію, щоб нам не довелося визначати joinклас для кожного класу колекції? Але чи не правда, що ми також можемо просто один раз написати для будь-якого класу колекції, наприклад у Ruby:

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

(щось подібне, закликаючи to_sкожен елемент, покладаючись на to_sкожен клас, щоб зробити свою власну справу, перетворити на рядок, а потім об'єднати їх). Тож нам не доведеться реалізовувати для кожного String, Hash або Set або будь-якого класу колекції, який ми маємо.

Або Python праворуч не йде маршрутом OOP? Він використовує, len("abc")а type([])замість "abc".len()або [].type()навіть у Python3 теж здається. Чи робить Python таким чином з дизайнерської причини?


7
З Дзен Пітона : "Має бути один-- і бажано лише один - очевидний спосіб зробити це. Хоча спочатку такий спосіб може не бути очевидним, якщо ви не голландці".
kdgregory

2
В одній формі колекція знає, як перетворити себе в рядок з роздільником, в іншому рядок знає, як об'єднати колекцію, використовуючи себе як роздільник. Вони обидва об'єктно-орієнтовані, але змінюють тему та предмет дієслова.
kdgregory

Maybe Python is more procedural?Python був процедурною мовою з кількома функціональними доповненнями ("Python придбав лямбда, зменшити (), фільтр () та карту (), люб'язно з хакера Lisp, який пропустив їх та подав робочі патчі") до тих пір, поки, здається, десь у версії 2. Це минуло близько півтора десятиліття після того, як над ним вперше працювали.

1
І навіть сьогодні Python навіть не намагається бути мовою ООП, це всебічно мульти-парадигма.

Як і C ++, Python - це мова, яка дозволяє OOP. Це не те саме, що мова OOP, як Java або Smalltalk.
Гурт Робота

Відповіді:


9

Пайтон приєднатися призначене для роботи на будь-який ітерації . Це означає, що дизайнерам довелося вирішити, куди його поставити. Оскільки він працює в більш ніж просто списках, але завжди вимагає (роздільник) і повертає рядок, вони вирішили зробити його частиною типу рядка.

Армін Ронахер каже, що це краще за мене:

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

"Уявіть, що Python не буде працювати таким чином. Вам слід спочатку перетворити ітерабеліз у фактичний список, щоб перетворити його в рядок. Рубінові люди тепер будуть стверджувати, що Ruby вирішує цю проблему зі змішуванням в модулях, і вони, безумовно, вірні, що це це варіант. Але це чітке дизайнерське рішення мовою, яка має багато наслідків. Python заохочує розв'язати зв'язок, маючи ці протоколи, де реальні реалізації можуть бути в іншому місці. Один об'єкт є ітерабельним, інша частина системи знає, як це зробити. в рядок. "


1
ОП свого роду намагається вирішити це за допомогою module Enumerateрозділу, але Python не працює таким чином, не існує єдиного суперкласу для всіх ітераторів, куди ви могли б поставити цей метод.

Я також спробував у Ruby 2.0 ... Hashі Stringнасправді не має колекційного класу як суперкласу ... їх суперклас просто Object. Тож ці два класи просто розраховують на те, що вони мають безліч міксин ... щось таке, наскільки я розумію, як інтерфейс, що передбачає набір поведінки колекції
неополярність

Тож це обмеження обмеження того факту, що "ітерабельний" - це не клас чи щось із фактичним кодом, а скоріше шаблон введення качки? Крім того, це просто тому, що Python хотів бути настільки загальним, щоб мати можливість працювати над будь-якою колекцією з однаковою реалізацією (тоді як багато інших стандартних бібліотек просто реалізували б її для кожної колекції, якщо вона насправді застосовується до цієї колекції).
Кет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.