LINUX.ORG.RU

Python3: private methods

 ,


0

1

Есть ли более простой способ для запрещения наследования конкретных методов класса?

#!/usr/bin/python3

class Библиотека(object):

  def азъ(self): print('азъ')
  def буки(self): print('буки')

class Интерфейс(object):

  protected_methods = ['буки',]

  def __init__(self): self._wrapped = Библиотека()

  def __getattr__(self, name):

    if name in Интерфейс.protected_methods: raise AttributeError
    return getattr(self._wrapped, name)

class Пустышка(Интерфейс):

  азъ = property()
  буки = property()

if __name__ == '__main__':

  c = Пустышка()

  print('protected methods:', c.protected_methods)

  print('c.азъ:', hasattr(c, 'азъ'))
  print('c.буки:', hasattr(c, 'буки'))

  print('c.азъ():', end = ' ')
  c.азъ()

  print('c.буки():', end = ' ')
  c.буки()

По-моему, в Turbo Pascal это делалось просто, указанием директивы private:

URL: https://stackoverflow.com/a/235657/966789

простой способ для запрещения наследования конкретных методов класса

Зачем? Можно же просто не дёргать «приватные» методы.

vvn_black ★★★★★
()

Просто добавь знак подчеркивания в имя метода. По соглашению пользователь будет знать, что его не надо переопределять, а если переопределит и у него что-то сломается, то он сам будет виноват.

Ещё можно в документации написать Do not override!!!

Питон не про строгие ограничения для типов, за этим в другие языки. Впрочем, и там всё можно обойти в крайнем случае изменением твоего исходника.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 1)
Ответ на: комментарий от KivApple

Просто добавь знак подчеркивания в имя метода. По соглашению пользователь будет знать, что его не надо переопределять

Это соглашение именно про запрет на переопределение?

Т.е., вызов такого метода _func извне - это норма?

i_am_not_ai
() автор топика

Все эти запреты по большому счёту не нужны в Python. Тем более, что в посте явно проблема XY, то есть очевидно, что попытка запрета преследует какую-то другую цель, о которой мы не знаем. Лучше явно указать, какую проблему пытаешься решить.

И ещё: в Python 3 нет необходимости наследовать всё от object.

emorozov
()

Нет.

Если хочешь сделать private, то используй костыль – два подчеркивания, при трансляции там добавляются два подчеркивания и соотв. получается перекрытие и ты просто так к таким функциям не обратишься.

Питон это не про защищенный, надежный код, это про то, чтобы очень быстро попробовать что получится, а если выгорит и будет круто, то потом переписать на языке для production.

PS: не используй символы отличные от ASCII для именования переменных, огребешь много проблем в будущем.

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

Питон это не про защищенный … код.

По мне вся эта «private» «защищенность» из C++ и Java — самый переоцененный бесполезный конструкт ООП. Точнее, смутно припоминаю, что для C++ это ещё имеет какой-то практический смысл из-за особенностей линковки.

Практического же смысла в подобной «защищенности» — 0.001%. В реальной жизни, проблемы в коде возникают совсем из-за других причин.

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

emorozov
()
Ответ на: комментарий от Morin

ну да ну да UB протекающих объектов это ведь так весело :)

Посмотрите на код из поста. Видно, что автор не читал даже туториал по Python 3 (например, наследование от object нынче не имеет никакого теоретического или практического смысла, это устаревшая конструкция из Python 2).

Что с большей вероятностью вызовет проблемы: отсутствие полноценного «private» в Python (хотя почти полноценный есть), или другие причины?..

Не веду статистики по классам ошибок, которые встречал в своей жизни, но сомневаюсь, что ошибки из-за недостаточной «закрытости» класса, заняли бы в таком списке хоть сколько-нибудь заметное место.

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

emorozov
()
Последнее исправление: emorozov (всего исправлений: 2)
Ответ на: комментарий от emorozov

автор не читал даже туториал по Python 3

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

Раньше, в начале карьеры, был перфекционистом, и писал программы «по правильному». Где-то даже создавал теоретический и методологический базис, почти фундаментальный труд )) Сейчас, спустя 20 лет, это уже выветрилось из головы.

i_am_not_ai
() автор топика
Последнее исправление: i_am_not_ai (всего исправлений: 1)
Ответ на: комментарий от i_am_not_ai

День плохих аналогий объявляется открытым.

Вот, есть объект, и у него есть палец и пипирка. Если тебе нужно дёргать за палец, будешь ли ты дёргать за пипирку, даже если она не прикрыта трусами?

vvn_black ★★★★★
()
Ответ на: комментарий от i_am_not_ai

Всё неиспользуемое выветривается из головы. Но не соглашусь, что более-менее длительный цикл жизни можно обеспечить без качества.

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

  1. Разобраться, что в нём к чему почти невозможно. Даже названия модулей, классов, функций и переменных часто лишены смысла или имеют названия противоположные тому, что делает метод или функция.
  2. Исправление бага приводит к появлению нескольких новых багов, т.к. всё очень тесно связано (coupled) друг с другом, вроде исправляешь ошибку, а на эту ошибку оказывается завязан десяток костылей в других частях кода, и рекурсивно получаем ворох проблем, который никак не сдвинуть с места.
  3. Добавление новой функциональности затруднено по тем же причинам: непонятно куда воткнуть, как воткнуть, чтобы не сломало существующую функциональность, и т.д.

Когда оттуда ушёл, отчаяние царило на всех уровнях: от директоров до самых последних разрабов и тестеров, т.к. никто не представляет, как из этой ямы выбраться.

Переписать всё - не вариант, нет денег и времени. Инкрементально улучшать - уходит прорва времени, результат незаметен, да и не всегда понятно, как можно постепенно улучшать Big Ball of Mud.

Поэтому ещё раз осознал, что на качество кода забивать всё же нельзя - рано или поздно аукнется.

emorozov
()
Последнее исправление: emorozov (всего исправлений: 1)
Ответ на: комментарий от emorozov

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

Вот, никогда не отождествлял инкапсуляцию с «спрятать своё от других». Я не прошёл бы собеседование?

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Вот, никогда не отождествял инкапсуляцию с «спрятать своё от других». Я не прошёл бы собеседование?

Да я не об этом, такого определения нет. Просто за годы работы, ревьюя код, обратил внимание, что джуны всегда подрываются всё густо залепить private, protected (в python всё обмазать андескорами, чтобы в глазах рябило).

Эти слова имеют какой-то магический эффект: когда люди (неопытные) их видят, они начинают заслонять им всё остальное.

Кстати, и во многих курсах по ООП-языкам, эту дребедень вставляют прямо в самое начало курса или книги, тогда как новичкам, наверное, стоило бы это объяснять в конце, или вообще не объяснять - т.к. всё равно не поймут или неправильно поймут.

Короче, есть множество более важных вещей, чем это.

P.S. Вспомним Java: там всегда все писали (и это поощрялось всеми книгами и даже IDE) private атрибуты, и автоматом get и set для каждого. Ужасно многословно, а толку почти ноль. Скорее антипаттерн. Но все повторяли не думая (и, возможно, повторяют до сих пор).

emorozov
()
Последнее исправление: emorozov (всего исправлений: 1)
Ответ на: комментарий от emorozov

По мне вся эта «private» «защищенность» из C++ и Java — самый переоцененный бесполезный конструкт ООП. Точнее, смутно припоминаю, что для C++ это ещё имеет какой-то практический смысл из-за особенностей линковки.

Практического же смысла в подобной «защищенности» — 0.001%. В реальной жизни, проблемы в коде возникают совсем из-за других причин.

Просто очень многие путают «защищенность» и «сокрытие сложности». Защищенный от коллег код, при совместной разработке, средствами языка не сделаешь, да, есть много инструментов, конвенций и методов, которые позволяют не стрелять себе и своим коллегам по ногам, но если их не соблюдать, то никакой синтаксис не поможет, в тех же С/С++ можно const переменным менять значение (если несколько исхитриться).

А вот сокрытие сложности это важно, оно позволяет сильно упростить взаимодействие между разработчиками, упростить проектирование и сопровождение продукта. Когда у тебя из класса торчит только пара методов, а все остальное private, то область контроля сильно сужается, аналогично и с интерфейсами библиотек, и с прочими механизмами, ООП это только один из способов.

soomrack ★★★★★
()
Ответ на: комментарий от emorozov

private, protected

Когда изучал Turbo Pascal with objects, наш учитель информатики никогда не упоминал про какие-то преимущества этих лексем, кроме удобства обозначения семантики.

Соответственно, ни на олимпиадах, ни в практической области, они никогда не требовались.

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

Вот и думаю… как задокументировать API, чтобы программист понимал - что можно переопределять, а что - нет.

Впервые готовлю прототип к продакшену. Приходится наступать на многие грабли, в т.ч. с рефакторингом ещё вненяемого легаси.

i_am_not_ai
() автор топика
Ответ на: комментарий от emorozov

Это не качество кода, это проблема менеджмента. По моему опыту (сравнительно небольшому) вначале нужно сделать альфа версию продукта как можно быстрее. Потому что денег мало, потому что надо ее выкинуть на рынок и понять правильно ли удовлетворяем спрос, потому что надо понять потенциальный объем спроса, потому что разработчикам нужна мотивация от работающего продукта и пр. На этом этапе качество кода не играет роли, если оно позволяет сделать альфа версию, важна скорость. Тут код пишут стартаперы, которые горят идеей и которые выдают километры мутного кода за сутки.

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

Довольно часто вторую стадию не делают как надо, а тупо продолжают рефакторить или просто костылить код из первой стадии, это приводит к описанной тобой ситуации. Продукт умирает, когда спрос еще есть.

soomrack ★★★★★
()
Ответ на: комментарий от i_am_not_ai

Вот и думаю… как задокументировать API, чтобы программист понимал - что можно переопределять, а что - нет.

Так и документируй, прямо в коде, «этот метод переопределять нельзя».

soomrack ★★★★★
()
Ответ на: комментарий от i_am_not_ai

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

Вот и думаю… как задокументировать API, чтобы программист понимал - что можно переопределять, а что - нет.

Просто начинай имена таких методов с подчёркивания. Если программист решит это переопределять — ССЗБ. Такова конвенция.

CrX ★★★★★
()
Ответ на: комментарий от i_am_not_ai

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

Документируй API и не твоя забота, кто и что там будет переопределять.

vvn_black ★★★★★
()
Ответ на: комментарий от i_am_not_ai

PS: Хорошая документация отличается от плохой тем, что в хорошая это не только про то, что код делает, это больше про то когда надо и когда не надо его использовать.

soomrack ★★★★★
()
Ответ на: комментарий от emorozov

Практического же смысла в подобной «защищенности» — 0.001%

А практический смысл ООП вообще тянет хоть на 0.1%? По идее питонофанбой должен немедленно кинуться на амбразуру защищая оопню. Но вот приватность он обязательно станет пинать и развернуто объяснять почему это нинужна. Потому что пистон это секта.

bread
()
Ответ на: комментарий от qulinxao3

Ну… в принципе, TP 6.0 хоть немного и подтормаживал на медленных машинах - был заметен небольшой лаг UI, но было конценпутально правильно всё. В BP, да - началась толстота.

Кстати, Филипп Кан не был единственным разработчиком этого комплекса инструментов, как иногда представляют. Там шли поглощения и перепродажи компаний, с начала 1980-х годов, и до 2009-2013х примерно.

i_am_not_ai
() автор топика
Ответ на: комментарий от token_polyak

яр тонко

На самом деле. Денис пошёл по неверному пути. Надо было вначале интегрировать кириллицу и глаголицу. Добавить помимо нуля и единицы - пару других символов в логику предикатов. Тогда бы работа пошла. Любой крупный инвестор заметил бы стартап издалека, и нанял пилить какой-нибудь бэкенд с оптимизацией.

i_am_not_ai
() автор топика