Почему в Python нет явных модификаторов доступа:

28

Если «явный лучше, чем неявный», то почему в Python нет явных модификаторов доступа: Public, Protected, Private и т. Д.?

Я знаю, что идея заключается в том, что программист должен знать, что делать с помощью подсказки - не нужно использовать «грубую силу». Но IMO «Инкапсуляция» или «сокрытие информации» - это не просто удержание людей, это вопрос организации и структуры: ваши уровни разработки должны иметь самоопределяющиеся, четко разграниченные области и границы, как это делают физические системы.

Может кто-нибудь, пожалуйста, помогите мне с ясным объяснением того, почему ограничения доступа подразумеваются, а не явны в Python, языке, который в других отношениях кажется близким к идеальному?

Изменить: Пока я видел 3 предложенных ответа, и я понял, что есть 2 части на мой вопрос:

  1. Почему нет ключевых слов, например

    private def myFunc(): 
        dostuff....

    вместо ИМО уродливые и трудные для подчеркивания. Но это не важный момент.

  2. Важнее:

    Почему эти модификаторы доступа являются «рекомендациями» или подсказками и не применяются. Это будет трудно изменить позже? Очень просто изменить «защищенный» на «общедоступный» - и если у вас сложная цепочка наследования, которая усложняет процесс, у вас плохой дизайн - ваш дизайн должен быть усовершенствован, а не полагаться на языковую функцию, которая облегчает написание плохо структурированный код

    Когда применяются модификаторы доступа, ваш код автоматически разделяется - вы ЗНАЕТЕ, что определенные сегменты находятся вне области видимости, поэтому вам не нужно иметь с ними дело, за исключением случаев, когда это необходимо. И, если ваш дизайн не подходит, и вы обнаруживаете, что постоянно перемещаете вещи в разные области видимости, язык может помочь вам привести себя в порядок.

Столько, сколько я люблю Python, я считаю, что этот второй пункт является серьезным недостатком. И мне еще предстоит увидеть хороший ответ на это.

Вектор
источник
возможный дубликат спецификаторов Access в Python: ... который был закрыт как неконструктивный.
Фрэнк Шиарар
2
@ Честно говоря, это повторный вопрос, чтобы попытаться быть более конструктивным. Я пошел дальше и удалил оригинальный вопрос.
@ Марк Трапп: Ах, хорошо. Благодарю за разъяснение. Я не вижу, как отменить свой голос до закрытия.
Фрэнк Шиарар
@Frank Это будет стареть само по себе.
Адам Лир
проблема в private def whateverтом, что class x: def whatever(self): passэто сокращение class x: pass; x.whatever = lambda self: pass, поэтому в основном вам понадобится частный модификатор для назначения
keppla

Ответы:

22

«Явное лучше, чем неявное» - это только одна из максим в философии дизайна Python. «Простое лучше, чем сложное». И, хотя это не в дзен Python, «мы все здесь взрослые по обоюдному согласию» - это другое.

Это второе правило, пожалуй, самое важное здесь. Когда я разрабатываю класс, у меня есть представление о том, как он будет использоваться. Но я не могу предсказать все возможные варианты использования. Это может быть , что некоторые используют будущее моего кода требуется доступ к переменным я думал , как частные. Почему я должен затруднять (или даже вообще невозможен) доступ к ним, если они нужны будущему программисту (или даже мне)? Лучше всего пометить их предупреждением - как отмечает Джунас, единый префикс подчеркивания является стандартом - что они являются внутренними и могут измениться; но запрещать доступ вообще кажется ненужным.

Даниэль Роузман
источник
1
«Простые лучше, чем сложные» и «Мы все здесь взрослые», поэтому Smalltalk не имеет модификаторов доступа. Помещение метода в «частную» категорию - это подсказка, что вы должны подумать трижды, прежде чем использовать его, и не более того.
Фрэнк Шеарар
@Frank: «Помещение метода в категорию« private »- это намек на то, что вы должны подумать трижды, прежде чем его использовать, и не более». Для меня это просто означает, что мне не нужно беспокоиться об этом, когда я не имею дело с этим.
Вектор
8
Есть веская причина, почему запрещают доступ частным пользователям: потому что это может нарушить инварианты класса. Если вы не можете писать приватные члены, то не можете быть уверены, что ваш класс ведет себя правильно.
svick
7
«Почему я должен усложнять - или даже делать невозможным - доступ к ним, если они нужны будущему программисту (или даже мне)?» Потому что одним из основных принципов проектирования является разделение между интерфейсом (что обеспечивает фрагмент кода) и реализацией (как он это обеспечивает). Инкапсуляция служит для уменьшения сложности кода за счет уменьшения зависимостей между различными частями кода. Таким образом, public и private используются именно для упрощения кода, позволяя видеть только то, что нужно.
Джорджио
3
Не могу вывести больше. Модификаторы доступа продвигают две, вероятно, наиболее понятные концепции для сокращения сложности в большом программном обеспечении: инкапсуляция и разделение проблем. Неспособность служить ни одному из этих двух способов просто означает, что python не является хорошим языком ООП и не подходит для создания большого программного обеспечения, и в этом нет ничего плохого. Но оправдывая отсутствие таких возможностей, можно привести типичные аргументы для любителей, такие как «Зачем добавлять сложность, когда она не нужна?» это просто неправильно.
Даниэль Шин
10

Я подозреваю, что основной причиной отсутствия модификаторов доступа является простота

Как вы говорите, речь идет не о том, чтобы не пускать людей, а об организации, поэтому основной смысл «частного» заключается в том, что он отправляет сообщение пользователям вашего API «пожалуйста, не пишите код, который зависит от этого».

Легко сказать «по соглашению, _x или __x не должны использоваться вне класса», но в динамической объектной модели python было бы трудно даже придумать нотацию.

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

как отметить доступность?

Я думаю, это был компромисс. Если вы строго не можете с этим жить, я бы предложил ruby, который имеет аналогичный уровень абстракции и динамичности, но имеет объектную модель, которая позволяет модифицировать доступ.

keppla
источник
8
Я думаю, что это правильно, но ИМО, это ужасно. Для языка, который использует элегантность и читабельность в качестве торговых точек, написание __method__ довольно отвратительно и тупо.
Джигги
2
это не соглашение, __x__это «магия» (т. е. методы, вызываемые для включения языковой интеграции, такие как перегрузка операторов, итеративность и т. д.). Конвенция есть _x.
Кепла
6
Извините, я все еще думаю о Python. Я так стараюсь это любить, но такие вещи приводят меня в замешательство. Особенно сейчас, когда мне нужно запомнить значение того, сколько подчеркиваний имеет метод. С точки зрения OP, кажется, что явные модификаторы были бы более понятными. Краткость отличная, но она не может превзойти ясность. Вы тратите в 10 раз больше усилий на поддержание кода, чем на его создание.
Джигги
2
Мой пример не должен был показывать различное количество подчеркиваний, использование __init__было случайным. В этом примере устанавливаются некоторые свойства объекта, которые не известны во время компиляции, поэтому явный модификатор доступа вам не поможет.
Кеппла
5
@jiggy: «Я так стараюсь, чтобы это понравилось». Я пробовал 2 года - потом сдался. :-( Похоже, что это язык сценариев, который был взломан, чтобы вести себя как настоящий язык ООП. Я не могу представить, как написать большое и сложное приложение на Python, которое было бы хорошо разработано и читабельно. Как вы сказали, вы тратите в 10 раз больше усилий сохранение кода , чем строить его»Простые ООП и безопасный тип концепции требуют сумасшедшие хаки и обходные пути..
Векторная
8

Соглашение Python заключается в использовании префикса подчеркивания для защищенных / закрытых членов.

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

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

Joonas Pulakka
источник
2
«если вы можете сделать то же самое (с немного большей гибкостью) без специальных ключевых слов, язык будет меньше, а код будет более кратким». На мой взгляд, это обычно не так. (Даже если это может быть правдой с особым случаем модификаторов доступа)
BenjaminB