Чому в Python немає явних модифікаторів доступу:


28

Якщо "явний кращий за неявний", чому в Python немає явних модифікаторів доступу: Public, Protected, Private тощо?

Я знаю, що ідея полягає в тому, що програміст повинен знати, що робити через підказку - не потрібно використовувати «грубу силу». Але "Інкапсуляція" або "приховування інформації" ІМО - це не лише для того, щоб уникнути людей, це питання організації та структури: ваші шари розвитку повинні мати чітко визначені сфери та межі, як і фізичні системи.

Чи може хтось, будь ласка, допомогти мені тут, чітко пояснивши, чому обмеження доступу мають на увазі, а не явні в Python, мові, яка в іншому випадку здається близькою до ідеальної?

Редагувати: Поки я бачив 3 запропонованих відповіді, і зрозумів, що на моє запитання є 2 частини:

  1. Чому, наприклад, немає ключових слів

    private def myFunc(): 
        dostuff....
    

    замість IMO підкреслюють потворні та важкі підкреслення. Але це не важливий момент.

  2. Що ще більш важливо:

    Чому ці модифікатори доступу є лише «рекомендаціями» або підказками, а не застосовуються. Це буде важко змінити пізніше? Дуже просто змінити "захищений" на "публічний" - і якщо у вас є складний ланцюжок успадкування, який ускладнює, ви маєте поганий дизайн - ваш дизайн повинен бути вдосконалений, а не покладатися на мовну особливість, яка дозволяє легко писати погано структурований код.

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

Наскільки я люблю Python, я вважаю цей другий момент серйозним недоліком. І я ще не бачив гарної відповіді на це.


можливий дублікат специфікаторів Access в Python: ..., який було закрито як не конструктивне.
Френк Ширар

2
@Frank - це повторне запитання, щоб зробити його більш конструктивним. Я пішов вперед і видалив оригінальне запитання.

@ Марк Трапп: Ага. Дякуємо за роз’яснення. Я не бачу, як скасувати голосування на закриття.
Френк Ширар

@Frank Це старіє самостійно.
Адам Лір

проблема в private def whateverтому, що class x: def whatever(self): passце ярлик для class x: pass; x.whatever = lambda self: pass, тому в основному вам знадобиться приватний модифікатор для призначення
keppla

Відповіді:


22

"Явне краще, ніж неявне" - лише одна із сентенцій філософії дизайну Python. "Просте - краще, ніж складне". І хоча це не в дзен Питона, "Всі ми згодні на дорослих тут" - це інша.

Це друге правило, мабуть, найважливіше тут. Коли я проектую клас, я маю деяке уявлення про те, як його використовуватимуть. Але я не можу передбачити всіх можливих застосувань. Це може бути , деякі використовують майбутнє мого коду потрібен доступ до змінних я думав , як приватні. Чому я повинен зробити це важким - або навіть неможливим - отримати доступ до них, якщо майбутній програміст (або навіть майбутній я) потребує їх? Найкраще зробити це позначити їх попередженням - як зазначає Йоонас, єдиний префікс підкреслення є стандартним - про те, що вони є внутрішніми і можуть змінюватися; але заборона доступу взагалі видається непотрібною.


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

@Frank: "Переведення методу до категорії" приватний "- це натяк на те, що вам слід думати тричі, перш ніж використовувати його, і не більше". Для мене це просто означає, що мені не доведеться турбуватися про це, коли я не маю справу з цим.
Вектор

8
Є вагома причина, чому забороняти доступ приватним членам: адже це може зламати інваріантів класу. Якщо ви не можете написати приватних членів, то ви не можете бути впевнені, що ваш клас поводиться правильно.
svick

7
"Чому я можу зробити це важким - або навіть неможливим - отримати доступ до них, якщо майбутній програміст (або навіть майбутній я) потребує їх?" Тому що одним з основних принципів дизайну є розділення між інтерфейсом (що надає фрагмент коду) та реалізацією (як він це забезпечує). Інкапсуляція служить для зменшення складності коду за рахунок зменшення залежностей між різними частинами коду. Отже, публічні та приватні використовуються саме з метою спрощення коду, дозволяючи бачити лише те, що потрібно.
Джорджіо

3
Неможливо діагностувати більше. Модифікатори доступу сприяють двом, мабуть, найбільш зрозумілим поняттям, щоб зменшити складність у великому програмному забезпеченні: інкапсуляція та розділення проблем. Якщо не обслуговувати жодне з двох, просто означає, що python не є гарною мовою OOP, а також не підходить для створення великого програмного забезпечення, і в цьому немає нічого поганого. Але виправдовуючи відсутність таких особливостей типовими аргументами-любителями типу "Навіщо додавати складність, коли це не потрібно?" просто неправильно.
Даніель Шін

10

Я б підозрював, що основною причиною відсутності модифікаторів доступу є простота

Як ви говорите, справа не в тому, щоб утримувати людей, а не про організацію, тому головним моментом "приватного" є те, що він надсилає повідомлення користувачам вашої програми "будь ласка, не пишіть код, який залежить від цього".

Тривіально сказати: "за умовами, _x або __x не слід використовувати поза класом", але в динамічній об'єктній моделі python важко навіть придумати нотацію.

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

як відзначити доступність?

Я здогадуюсь, це була торгівля. Якщо ви категорично не можете з цим жити, я б запропонував рубін, який має аналогічний рівень абстракції та динамічності, але має об'єктну модель, яка дозволяє змінювати доступ.


8
Я думаю, що це правильно, але ІМО, це жахливо. Для мови, яка використовує елегантність та читаність в якості продажу точок написання __method__, досить прискіплива і тупа.
джиггі

2
це не умова, __x__це "магія" (тобто методи, які вимагають ввімкнення мовної інтеграції, наприклад, перевантаження оператора, ітерабельність тощо). Конвенція є _x.
keppla

6
Вибачте, я все ще головую навколо Python. Я так стараюся, щоб це сподобалось, але такі речі приводять трохи батти. Особливо зараз, коли мені потрібно запам'ятати значення того, скільки підкреслює метод. На думку ОП, видається, що явні модифікатори були б більш зрозумілими. Конкретність є чудовою, але вона не може домогтися ясності. Ви витрачаєте на 10 разів більше зусиль на підтримку коду, ніж на його створення.
джиггі

2
Мій приклад не мав на меті показувати різні підкреслення, використання цього __init__було випадковим. Приклад встановлює деякі властивості об'єкта, про які не відомо на час компіляції, тому явний модифікатор доступу вам не допоможе.
кеппла

5
@jiggy: "Я так намагаюся сподобатися". Я пробував 2 роки - тоді здався. :-( Виявляється мовою сценаріїв, яку зламали так, щоб поводитись як справжня мова OOP. Я не уявляю, як написати великий, складний додаток на Python, який був добре розроблений і читабельний. Як ви сказали: Ви витрачаєте на 10 разів більше зусиль підтримка коду, ніж його створення ". Простий OOP та безпечні концепції вимагають шалених хак та обхідних шляхів
Вектор

8

Конвенція Python полягає у використанні приставки підкреслення для захищених / приватних членів.

Ця угода, якщо за ним слід, фактично такий же , як модифікатори доступу, за винятком 1) ви будете бачити безпосередньо від учасника імені , будь то державні чи ні, і 2) ви можете зламати «інкапсуляція» , якщо ви дійсно хочете (це може бути виправдано напр. тестування; в деяких інших мовах вам доведеться використовувати віддзеркалення == більше коду).

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


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