#6. Режимы доступа public, private, protected. Сеттеры и геттеры | ООП Python
HTML-код
- Опубликовано: 22 ноя 2021
- Курс по Python ООП: stepik.org/a/116336
Узнаете, как реализуются режимы доступа public, private, protected для атрибутов в классах языка Python. Что такое сеттеры и геттеры и зачем они нужны. Улучшенная защита атрибутов через модуль accessify.
Инфо-сайт: proproprogs.ru/python_oop
Telegram-канал: t.me/python_selfedu
Очень надеюсь Сергей, что вы услышите наши мольбы и выложите курс по ООП на степик. После этих видео просто чешуться руки и хочется закрепить тему на задачах.
Два чаю этому господину. Поддерживаю
Величина таланта преподавателя зашкаливает! Умнейший человек
-Ты приватный метод?
- нет, я волшебный))
На Вашем канале наиболее доходчивая подача материала из тех, что мне пока встречались. Благодарю за проделанную работу и желаю успеха в любых Ваших начинаниях! :)
Ну наконец-то доходчиво человек объяснил для не самых умных :) спасибо!
У вас синдром "Самозванца"
Сергей, огромное спасибо за Ваши труды🙏
Толковый урок. Сергей, спасибо большое, открываете глаза
Спасибо Сергей за великолепный урок. Всё понятно и обстоятельно! Рад что вы взялись за обновление ООП.
ОЧЕНЬ понятно объясняете, спасибо вам огромное, Сергей!
смотрел как то видео, там java разработчик ругал геттеры и сеттеры. теперь придется пересмотреть все заново что бы понять суть его претензии. Большое спасибо за труд!!!!
Спасибо огромное, Сергей! Ваши уроки довольно исчерпывающие и развеивают в голове сложившиеся недопонимания и мифы, заполняют пробелы. Всё цельно и по полочкам)
Сергей, спасибо большое за урок!
Сергей, спасибо Вам огромное за эти уроки! Очень жду курс на Степике!
Очень рад, что наткнулся на Ваш канал. Материал дается последовательно и все очень доходчиво объясняется. Еще радует, что почти в каждом видео есть фишки, которые раньше не встречал. Пусть Ваш образовательный запал не иссякает)
Сергей, спасибо Вам огромное за этот бесценный материал! Очень системно и понятно объясняете, одно удовольствие изучать! 🤗
Сергей, спасибо за такой не легкий труд, за такое понятное и доходчивое объяснение
9:37 А почему не staticmethod? Мы же делаем простую проверку входных чисел, которые не относятся ни к экземплярам, ни к классу? Или же это так, на случай вдруг в будущем запихнуть туда какие-то атрибуты класса?)
Сергей, спасибо за понятные и полные объяснения! Раньше классы для меня были чем-то сложным и пугающим, сейчас пока всё понятно :)
Как всегда доступно и грамотно!
Сергей, спасибо большое за видео! Очень понятно все рассказываете! Было бы очень здорово, если бы у вас было больше тем с задачами на Степик)
Казалось бы, предыдущий плейлист по ООП на этом канале отличный. Но даже здесь Сергей смог улучшить и добавить новых полезностей. Спасибо за труд!
а потом еще лучше будет!
Вы просто гений в объяснении. От используемых слов до самого произношения. Очень уместно расставлены акценты . Смотришь как кино. Спасибо!
спасибо, очень информативный урок
Спасибо. Круто. Понравилось.
Сергей, благодарю! 👍💯
Отличный урок!
Спасибо за урок
Огромное спасибо за этот материал, теперь я реально начал что-то понимать, сидишь, смотришь и прям кайфуешь как от уровня полного нуля приходит осознание =) тут реально все разложено как для детей, в других курсах просто жесть из стиля: это конструктор, это деструктор - идите творите и сидишь такой из стиля, а что делать то?)))))
Спасибо большое!
Оптимальный по продолжительноти и объёму информации ролик. Можно хоть десять раз пересмотреть и повторить вслед за автором в PyCharm-е пока не придёт его величество Понимание.
Это самое лучшее и, по сути, единственное объяснение, которое помогло мне лучше всего разобраться в сеттерах и геттерах. Спасибо!
уроки конечно отличные, но ваш коммент приятнут за уши, про сеттеры и геттеры тут как раз упомянуто вскользь. автору спасибище!!!
@@diekunstUA Мне помогло - вот и все) Говорю искренне
Спасибо!!!
Спасибо!
максимлаьно полно, просто и доступно
какая жэсть) ради интереса сравните как работают модификаторы доступа к свойствам и константам класса в php 8
Судя по описанию, к атрибуту _protected есть доступ у дочерних экземпляров. Что и делалось в данном видео, но не совсем понятно в каких кейсах целесообразно использовать.
🙏 Спасибо!
Privat методы - это обработчики для гетеров, сетеров и прочих функций (например, проверка, чтобы str значение не записывали туда, где цифры)
Privat свойства - это переменные (часто это константы), которые нельзя менять просто так. Только внутриклассовыми методами.
Privat атрибуты защищены от случайного вызова снаружи класса (они недоступны). Рассчитаны только на использование внутри класса и только внутри, без наследования и т.п.
Protect свойства и методы - это служебные атрибуты класса, использовать можно снаружи, но на свой страх и риск, т.к. их могут изменить другие разработчики в любой момент.
Protect свойства и методы - рассчитаны на использование как в классе, так и для наследования в другие классы.
Ещё сеттеры могут быть полезны, если необходимо добавить некие вычисления.
лайк и комментарий в поддержку.
Приветствую Сергей спасибо за видео, очень ясно и познавательно. Подскажите предыдущий блок про ООП устарел или все же актуален?
лучше смотреть этот курс, в том есть недочеты, я его со временем уберу
11:20 сделал проверку через уже имеющийся метод set_coord и обнаружил, что ему нужно сразу передать x и y без self, иначе интепртетатор ругается. Заметил, что с методом __check_value мы поступили также - не передали при вызове cls, но тут метод класса. Не могли бы вы осветить данный вопрос? Все найденные объснения в гугле не содержат именно этого нюанса. Спасибо!
Спасибо за лучшие объяснения на русском!
P.S. Читается "аксе́сифай" :)
Можно было воспользоваться isinstance при формировании условий в методах?
с одним подчеркиванием прямо джентельменское соглашение - если хочется, то можно
Получается немного дублирования в сеттере, если мы определили входные параметры в __init__
10:09 почему мы объявили __check_value как classmethod а не staticmethod? Ведь он не обращается к аттрибутам/методам класса, а работает с переданными параметрами
да, здесь вполне подойдет статик
вопрос: через код-имени можно даже под защитой эксифай достать свойство?
👍👍👍👍👍
👍👍
Здравствуйте! А почему вы создали __check_value через classmethod, а не через обычный метод?
Все, что не подразумевается для выдачи пользователю (вне класса), следует помечать закрытым. Тогда открытые методы следует поддерживать в неизменяемом виде (в разных версиях класса), а закрытые можно изменять (сигнатуру и функционал).
👍
Сергей, будет ли курс по данной теме на Степике? Благодарю!
Посмотрим, пока незнаю.
Сергей, допустимо ли в методе __init__ для исключения дублирования кода, вызвать метод set_coords?
да и это хорошая практика
Полистал комментарии, ответа на свой вопрос не увидел. А он вот в чем. Мы изначально имеем метод __init__, в котором есть self.__x = 0, self.__y = 0. Далее объясняется что для изменения этих значений нужно создать отдельный set_coords, который будет уже заменять значения по вызову внешней ссылки pt.set_coords(1, 2). Но почему мы не можем просто взять тот же __init__ и написать условное pt.__init__(1, 2)? Замена происходит также как и при создании сеттера. Не могу понять смысла этого дополнительного действия
>Но почему мы не можем просто взять...
Потому что для этого есть специальные методы и нужно использовать их.
Питон просто допускает возможность выстрелить себе в ногу разными путями, но автором и документацией сразу оговаривается, что не надо так делать т.к. по какой-либо причине могут убрать __init__ из кода и придётся перепиливать куски кода
Кратко говоря: не надо ломать стекло, чтобы проветрить комнату
Здравствуйте. А не подскажите где можно взять задания для отработки ООП , в степике его так мало ,а вот вебе его весьма много ,не меньше чем циклов .
попробуйте более жизненную задачу - например есть сайт вакансий/фильмов/книг (не важно), на котором нет фильтрации/сортировки или фильтрация работает как-то не так как хотелось бы. Спарсить это все и вывести. Сделать на ооп и без.
только, наверно, лучше статический, а не класса
@staticmethod
def __check_value(x):
return type(x) in (int, float)
14:20 подскажите пожалуйста как вы быстро убрали два подчеркивания? какие горячие клавиши PyCharm использовали
это магия монтажа )))
@@selfedu_rus серьёзно? хм...
Сергей, допустимо ли в конструкторе класса __init__ делать так? Чтобы сразу делать проверку
class Point:
def __init__(self, x = 0, y = 0):
self.set_coord(x, y)
да, даже предпочтительно, только начальные значения локальных атрибутов self.x, self.y нужно создать, иначе если проверка не пройдет (в сеттере) локальных атрибутов не будет (обычно присваивают некие начальные значения)
@@selfedu_rus Спасибо, понял
@@selfedu_rus Только если запускать файл и давать изначально значения не проходящие проверку , то уже следующая строка не запускает метод , например метод get_coord для проверки , что были установлены значения 0 , 0. Так как сработало исключение.
Если запускать в консоли и делать то же самое поочередно , то все работает
Тогда как обращаться к методу check_value() который имеет декоратор @private @classmethod? Через имя класса Poin. ?
Вы имеете в виду режим доступа private? С нижним подчеркиванием? Проблем с доступом тут нет.
10:40 не проще было сделать статик методом вместо класс метода?
Благодарю за урок.
На 14.13 не понял почему убрали двойные подчёркивания у названия метода, но не убрали у названия атрибутов этого метода. Если атрибуты приватны, то и название метода было бы полезно указывать как приватное.
Так мы там используем декоратор @private, чтобы сделать его приватным. Убираю подчерктвание, чтобы продемнстрировать, что он действительно приватным становится.
в функции def __check_value(cls, x): можно писать и def __check_value(self, x): тем более, что работаем с экземпляром класса pt -> pt.set_coord(10,20). Зачем все таки писали cls в параметре, если работает и self ?
__check_value() не работает с self, туда передается параметр, он проверяется (можно вместо classmethod взять staticmethod будет лучше)
а где можно дополнительно прочитать в каких случаях рекомендуется использование тех или иных режимов доступа?
@@AntonyKondr ок
какую практическую эффективность в данном случае нам дает то, что мы сделали __check_value методом класса? Или это просто как сигнал разработчику что это метод класса? Что будет, если мы его запишем как обычный метод:
def __check_value(self, x):
return type(x) in (int, float)
Это как то плохо повлияет на наш код?
все внутренние методы класса лучше помечать одним или двумя подчеркиваниями (так пользователям класса понятно, что это не публичный метод)
@@selfedu_rus это я понял, я о другом. Я не понимаю зачем мы этот метод делаем методом класса, что это нам дает? Почему здесь используется код
@classmethod
def __check_value(cls, x):
return type(x) in (int, float)
а не
def __check_value(self, x):
return type(x) in (int, float)
Я просто не понимаю почему мы здесь используем метод класса, а не обычный метод
@@Pro100Fart правил на этот счет особых нет, это как говорить на иностранном, одну и ту же мысль можно донести разными предложениями. Постигается с опытом.
Здравствуйте! Поясните, пожалуйста, такой момент. После добавления двух символов _ _перед переменной, ее нельзя вывести в принт, через внешнюю ссылку pt.__x. Но при этом, атрибут легко меняется по внешней ссылке, например, pt.__x = 9.(без всяких сеттеров). А после такой замены ( хотя она вроде как не должна работать), переменная с двумя подчеркиваниями легко выводится в принт через ту же самую команду pt.__x Почему так?
Интересный моменты вы отметили )) Но объясняется очень просто. Когда извне создаете локальный объект (с любым именем), то он создается как глобальный. То есть в строчке pt.__x = 9 создается новый локальный атрибут с именем __x. Когда же мы внутри класса создаем self.__x, то имеем другой локальный атрибут (приватный), но он имеет также глобальное имя _имякласса__x. Вы можете в этом убедиться, распечатав: print(pt.__dict__). Там у вас будет дополнительный атрибут глобальный __x
@@selfedu_rus Спасибо большое за пояснения! В целом понятно! Не совсем ясно только, в чем тогда защита переменных. Ведь получается, мы создаем объект класса командой pt = Point(1, 1) . При этом через __init__ этому создаваемому объекту pt присваиваются 2 новых локальных атрибута self.__x и self.__y (это же считается как создание внутри класса?). И эти параметры недоступны по внешней ссылке pt. Но, решив поменять значения, написав pt.__x = 9, они получается становятся глобальными и легкодоступными? В чем тогда защита...Или для защиты тогда нужно обязательно использовать __setattr__?
@@user-pv6ut2uo3t нет, вы создаете новый локальный атрибут, те защищенные остаются без изменений
@@selfedu_rus вроде понятно, а вроде и не до конца. Получается у объекта pt появляется 2 атрибута, pt.__dict__ выводит их { '_Point__x' : 1, '__x' : 9 }. Видимо один локальный, который определен внутри класса. А второй глобальный, так? Это по аналогии с локальными и глобальными пространствами имен у функций?
@@user-pv6ut2uo3t нет, посмотрите занятие по Python ООП, где я рассказываю про разграничение доступа: proproprogs.ru/python_oop/rezhimy-dostupa-public-private-protected-settery-i-gettery
Можнали изменить специальное имя этих двух подчеркиваний?
недопонимание на Private инкапсуляции:на примере 4:43, у нас есть
class Point:
def __init__(self, x=0, y=0):
self.__x = x
self.__y = y
Ошибка на выполнении print(pt.__x, pt.__y). Но разве 'pt' не находится внутри класса Point?
При этом далее, при присвоении и возврате значений методами set_coord и get_coord через экземпляр pt, значения успешно присвоены и возвращены (тут логично, экземпляр pt и другие возможные внутри одного класса вроде как)
или там логика в том, что для set_coord и get_coord мы присываем атрибуты именно переменным x, y в (self, x, y) , которые в свою очередь дают значение инкапсулированным __x и __y в (self.__x, self.__y).
Если это всё так, то остался вопрос: pt находится внутри класса Point? 🙃
pt - это внешняя ссылка на объект класса Point
Досмотрел до того места где рассказывается о том, что одно нижнее подчеркивание никак не модефицирует доступ к полю класса и по сути не делает его protected, а является 'сигналом' для программиста... после cpp это просто уже кровь из глаз... Сейчас немножко отойду и дальше смотреть буду. :) Python конечно странный язык. :)
Почему в разных источниках про protected дают разную инфу? В одних говорят что зона действия Класс и его Наследники. А в других - Модуль и даже Пакет. Что же правильно в итоге???
Модуль и пакеты - тоже верно )
Если "__init__()" и get_coord() выполняет то же самое, можно ли тогда в "__init__" вызвать get_coord()?
set_coord() вы имели в виду? Да, это нормальная практика.
Не понял, зачем или по какой причине check_value определили методом класса? Что это дало, он же работает с параметрами передаваемыми в экземпляр при инстанцировании? Почему это метод класса тогда (если работает с параметрами. переданными на вход через экземпляр при инстанцировании, а не с внутренними каким-то полями самого класса)
check_value работает с данными, которые ему передаются через параметры, а не напрямую с атрибутами объекта класса, поэтому его вполне можно сделать методом класса; если сделаете обычным методом, ошибки не будет
@@selfedu_rus а, стало яснее, спасибо! Эту разницу между данными, переданными в параметры, и сами атрибутами я упустил 😳
А почему так в питоне устроено все? Почему можно все таки к private атрибутам обращаться? Есть какой-то аргумент в пользу этого?
По задумке (Гвидо Ван Россума) все должно быть явным, никаких скрытых факторов. Здесь доступ к закрытым свойствам - на совести программиста.
@protected работает также как @private,или есть отличия?
конечно, есть, @protected - можно внутри класса и во всех дочерних, @private - только внутри текущего класса
@@selfedu_rus Спасибо!
Что то не пойму, кто знает помогите, или кто понял. В методе def __init__(self, x=0, y=0) - начальные значения же здесь указаны? Зачем ниже строчка - self.__x = self.__y = 0?
создаются локальные приватные атрибуты __x и __y, иначе бы они не создались бы
@@selfedu_rus Создаются они строкой self.x = x? А тут наверно задаются значения локальным свойствам класса, которые применяются когда введено не верное значение в экземпляре класса, при вызове метода класса? Если более детально в строке init - значение по умолчанию(x = 0, y = 0), в экземпляре класса в строке pt = Point(1, 2) - присваиваются новые значения и если они не пройдут проверку(__check_value), то тогда работает строка self.__x = self.__y = значение которое будет присвоено, хоть строка.
@@Receive_ да, если x и y не проходят check value, то им присваивается 0
может я не понял, но когда мы пишем print(pt.__x), то выходит ошибка (как и должно быть). Но в то же время мы можем написать pt.__x = 500 и программа отработает. ну и если смотреть переменные в консоле, то там вообще всё запутывается ещё больше. спасибо.
при pt.__x = 500 создается локальный атрибут __x и он не имеет никакого отношения к приватной переменной __x
@@selfedu_rus спасибо за быстрый ответ и за курс :)
Есть способ ограничить класс от самого себя?)
только если не писать его ))
Обратился к двум подчеркиваниям вне класса - сам себе страшный Буратино!
Читаю комментарии после просмотра видео несколько раз, и понимаю что походу тут самый непонятливый это я:( Что означает эта защита. Защита от кого или от чего?))
Защита от доступа "извне" (для программиста, который это будет использовать); защита от наследования и т.д. Только "защита" несколько условная, скорее, указание программисту, что этот метод или переменную трогать не надо, она для внутренней кухни класса ))
Ну... Если хорошенько подумать то в python вообще нету инкапсуляции.
👍👍👏👏🫡
accessify - эксэссифай, а не эксифай.
почему нельзя отдать тебе все лайки которые я когда либо ставил, а, они и так все у тебя
Все-таки "эксесифай", а не "эксифай")
Здравствуйте! Спасибо Вам за работу!
Хотел попросить записать курс, если есть такая возможность, по методам разработки больших приложений
Подскажите, пожалуйста, можно ли в пользовательском классе, подобно встроенным классам, сделать полную защиту от внешнего вмешательства (относительно всего - добавления, изменения или удаления свойств экземпляров класса и свойств и методов самого класса)?
на уровне языка Python можно защититься, используя магические методы delitem, delattr и другие подобные (о них рассказ впереди)
@@selfedu_rus Но тогда не очень понятно, если защиту можно сконструировать при помощи магических методов, зачем нужны эти режимы доступа? Например, тот же запрет на прямое (не через сеттер) изменение какого-либо свойства экземпляра класса можно прописать в методе __setattr__ , не обращаясь к private. И, по-моему, так даже надежнее (может, я чего-то не знаю). Объясните, пожалуйста.
@selfedu_rus Почему вы в каких-то случаях говорите Свойства, в каких-то Данные, а в каких-то Атрибуты?
свойства объекта класса и локальные атрибуты объекта для меня это синонимы
можете сказать зачем здесь @classmethod если можно было просто написать без него (ваще не разобрался зачем нужен classmethod, только если брать переменные класса и все, сколько я б не перечитывал инфы зачем он нужен, я все равно так и не понял)
в classmethod первым параметром передается класс, а не его экземпляр, благодаря этому непосредственно в классе можно создавать и изменять атрибуты
@@selfedu_rusспс дружище
Спасибо!
👍
Спасибо!