Навіщо тобі потрібно «я». в Python для позначення змінних екземплярів?


13

Я програмував на декілька мов, таких як Java, Ruby, Haskell і Python. Мені доводиться перемикатися між багатьма мовами на день через різні проекти, над якими я працюю. Тепер проблема полягає в тому, що я часто забуваю писати, selfяк перший параметр у визначеннях функції в Python те саме відбувається з методами виклику на одному об'єкті.

Це сказав, що я дуже вражений таким підходом Пітона. В основному нам доводиться набирати більше, щоб все було зроблено, в таких мовах, як Java та Ruby, речі спрощуються шляхом автоматичного посилання на змінні в поточному об'єкті.

Моє запитання, чому це selfпотрібно? Це виключно вибір стилю, чи є причина, чому Python не може дозволити вам опустити selfтак, як Java та C ++ дозволяють вам опуститись this?



1
@gnat тепер лише плюси, і якщо це серйозно, це гарне питання, яке клопоче мене з кількох днів, будь ласка, не вбивайте його за допомогою голосування.
vivek

2
Це питання було більш ніж ретельно висвітлено статкомverflow.com/ questions/ 2709821/… .
Девід Арно

Я розумію, що він заснований на стилі С передачі вказівника на структуру в якості першого аргументу.
Даннно

Запис @staticmethodперед оголошенням методу пригнічує помилку (лише для інформації, а також не рекомендується)
Yash

Відповіді:


23

1) Чому selfв підписах методу потрібен явний параметр?

Тому що методи - це функції, і foo.bar(baz)це просто синтаксичний цукор bar(foo, baz). Класи - це лише словники, де деякі значення є функціями. (Конструктори - це також просто функції, тому Python не потрібен new) Ви можете сказати, що Python робить явним, що об'єкти будуються з більш простих компонентів. Це відповідно до "явної краще, ніж неявної" -філософії.

На відміну від цього, об'єкти Java справді є магічними, і їх не можна звести до більш простих компонентів мови. У Java (принаймні до Java 8) функція - це завжди метод, що належить об'єкту, і це право власності не може бути змінено через статичну природу мови. Тому немає жодної неоднозначності щодо того, на що thisйдеться, тому має сенс чітко визначити це.

JavaScript є прикладом мови, яка має неявну форму, thisяк Java, але функції можуть існувати окремо від об'єктів, як у Python. Це призводить до великої плутанини щодо того, що thisстосується, коли функції передаються навколо та викликаються в різних контекстах. Багато інстинктивно думають, що вони thisповинні посилатися на якусь властиву функцію, в той час як вона насправді суто визначається способом виклику функції. Я вважаю, що thisнаявність явного параметра, як у Python, зробить це набагато менш заплутаним.

Деякі інші переваги явного параметра self:

  • Декоратори - це лише функції, які охоплюють інші функції. Оскільки методи - це лише функції, декоратори працюють так само добре, як і методи. Якби була якась неявна самостійна, декоратори не працювали б прозоро над методами.

  • Класметоди та статичні методи не приймають параметр екземпляра. Classmethods приймають клас як перший аргумент (як правило, його називають cls). Явні параметри selfчи clsпараметри значно зрозуміліші, що відбувається, і до чого у вас є доступ у методі.

2) Чому для змінних примірників завжди можна кваліфікувати " self.?

У Java вам не потрібно префіксувати змінні члена " this.", але в Python self.завжди потрібен "". Причина полягає в тому, що Python не має явного синтаксису для декларування змінних, тому не було б можливості сказати, чи x = 7слід оголошувати нову локальну змінну або призначити змінну члена. Вказання self.вирішує цю неоднозначність.


Неявна посилання на змінну членів (без self., як у Java) принципово несумісна з правилами розміщення, і коли вам потрібно бути явним там, відсутність неявного параметра не має сенсу більше.
Ян Худек

@JanHudec: Добре, крапка. Я додав це до відповіді.
ЖакБ

6

Існує досить проста причина, що AFAIK насправді не торкався у дублікаті між веб-сайтами, ні тут: Python почався як процедурна мова. Він базувався на ABC, також процедурній мові.

Об'єкт-орієнтація була додана пізніше, і коли вона була додана, Гвідо ван Россум хотів додати мінімально можливу кількість функцій, щоб зробити дизайн Python простим. У Python вже були dicts та функції, тож чому додати щось абсолютно нове до мови, коли об’єкт може бути просто dictслотами, а клас може бути просто dictфункцією? Метод можна інтерпретувати як частково застосовану функцію, яка закривається над одним розрізненим аргументом. І саме так реалізуються методи в Python: вони не є. Вони є лише функціями, які отримують додатковий аргумент.


Я вважаю, що Python підтримував ОО і мав класи та успадкування з першої випущеної версії. Принаймні, так мені каже вікіпедія. Але процес Ван Россумса в початковому дизайні мови міг бути, як ви описуєте.
ЖакБ


Дякую за посилання, це справді цікаве читання.
ЖакБ

2

Ось мої висновки на основі вищезазначених відповідей та прочитання власної суперечки Гвідо на цю тему:

Велика ідея

Функції є важливими будівельними блоками в Python (або слід сказати єдиний), адже ми начебто наслідуємо OOP за допомогою функцій.

Зважаючи на те, що клас - це не що інше, як словник функцій, отже, ми можемо приєднати будь-яку функцію до будь-якого класу під час виконання. В основному саме тому, що через це потрібно перекидати функції на час виконання, ми можемо робити такі речі, як Monkey Patching . Тут selfпараметр, що підтримує параметричний поліморфізм.


1
Питання з самовідповіддю рекомендуються, коли ваша відповідь - це якісна відповідь. Коли я порівнюю тут вашу відповідь з іншими відповідями, мені залишається цікаво, чому ви відчули, що вам потрібно це додати. Інші відповіді заглиблюються і додають більше деталей, ніж те, що робить ваша відповідь.

1
@ GlenH7 відповідь була тільки для моєї довідки, тому що кожного разу я не можу приходити і читати відповідь кожного знову і знову. Що стосується якості, то скажіть, чи будь-яка частина інформації вводить в оману. Я завжди чекаю 2-3 дні, щоб прийняти будь-яку відповідь.
vivek

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