#8. Паттерн "Моносостояние" | Объектно-ориентированное программирование Python

Поделиться
HTML-код
  • Опубликовано: 26 ноя 2021
  • Курс по Python ООП: stepik.org/a/116336
    Делаем класс, у которого объекты имеют единое локальное пространство, единые локальные атрибуты - паттерн "Моносостояние".
    Плейлист по Python ООП: • Объектно-ориентированн...
    Инфо-сайт: proproprogs.ru/python_oop
    Telegram-канал: t.me/python_selfedu

Комментарии • 105

  • @nazarkhort4362
    @nazarkhort4362 2 года назад +174

    Паттерны проектирования: порождающие, структурные, поведенчиские. Пожалуйста, Сергей! Если сделать отдельные видео, где объяснить кратко о каждом, на простом примере кода и добавить их потом в плейлист, то это будет топ в ютюбе! Услыште нас! Мы хотим паттерны.
    Парни поставте лайк, чтоб Сергей увидел.

  • @user-fk4dx7sc8r
    @user-fk4dx7sc8r 2 года назад +36

    Такого наставника хотели бы многие студенты.Спасибо вам огромное

  • @nazarkhort4362
    @nazarkhort4362 2 года назад +25

    Ура, ура паттерны пошли. Сергей, пожалуйста продолжайте про паттерны. Мы хотим паттерны с примерами!

  • @heshagrade
    @heshagrade 2 года назад +18

    Интересная вещь, хотя и пришлось немного поломать мозги, чтобы понять до конца, почему оно работает именно так. Долго не мог понять, как после обозначения нового атрибута "th1.attr_new" он попадает в "__shared_attrs"? Пришлось покопать и потом дошло, что "__dict__" лишь указывает на словарь, который в данном случае является свойством класса, общим для всех экземпляров.
    Другими словами, строку
    th1.attr_new = "new_attr"
    нагляднее можно записать так:
    th1.__dict__["attr_new"] = "new_attr" - то есть через "__dict__" мы обращаемся к словарю, на который "__dict__" указывает, и создаём там новую пару ключ-значение, что одновременно является новым атрибутом класса.

    • @user-no9zt9dh4o
      @user-no9zt9dh4o Год назад +2

      но у нас же должны только shared_attr быть локальными, как он добавляется то...

    • @user-rd3wq8gf7q
      @user-rd3wq8gf7q Год назад +2

      @@user-no9zt9dh4o Мне тоже долго пришлось понять, но, все-таки дошло. если кеу нет в __shared_attr то он просто добавляет это значение в предыдущую словарь, а если есть то обновляет значение.
      class Point:
      fuck = {'first': 1, 'second': 2}
      def __init__(self):
      self.__dict__ = {'its me': 456}
      p = Point()
      p.__dict__
      >> {'its me': 456}
      p.newer = 'new!!!'
      p.__dict__
      >>{'its me': 456, 'newer': 'new!!!'}
      p.newer = 'i am already old :('
      p.__dict__
      >>{'its me': 456, 'newer': 'i am already old :('}

    • @HubaBuba2007
      @HubaBuba2007 20 дней назад +1

      проще говоря, мы создаем новое значение в __shared_attrs?

    • @wotlivehannel4612
      @wotlivehannel4612 17 дней назад

      @@HubaBuba2007 да

  • @user-jo5ij6df1d
    @user-jo5ij6df1d Год назад +6

    Информация из ролика ещё дополняется крупицами информации из комментариев.

  • @igorb.4917
    @igorb.4917 2 года назад +4

    Спасибо, с нетерпением жду каждого нового урока.

  • @user-ee1lx1pe7n
    @user-ee1lx1pe7n 2 года назад +6

    Спасибо огромное! Да, ждем отдельный плейлист про паттерны)

  • @user-br7hg4by2j
    @user-br7hg4by2j 2 года назад +3

    Сергей, большое спасибо, очень полезный урок!

  • @evkny
    @evkny 2 года назад +4

    Спасибо вам большое за ваш труд. Очень полезные уроки

  • @donfedor007
    @donfedor007 2 года назад +5

    Спасибо! Очень интересно! Паттерны это интересная тема!

  • @86Blind
    @86Blind 2 года назад +4

    Спасибо за уроки!

  • @mslq
    @mslq Год назад +2

    Спасибо большое, у вас самое подробные уроки в отличии от остальных блогеров, да ещё они вздумали своими школами обзавестись, так что от них нечего чего то ждать существенного.

  • @vladimirastrelin1719
    @vladimirastrelin1719 2 месяца назад +1

    Интересная тема, спасибо, Сергей!

  • @user-ym4mj1pg3h
    @user-ym4mj1pg3h 3 месяца назад +2

    Короче, кто не понял магии.
    У экземпляра класса есть свои локальные атрибуты. Они хранятся в __dict__. Это словарь, который автоматически создаётся при создании объекта (или инициализации, хз). Но в данном паттерне мы как бы подменяем родной __dict__ экземпляра на __shared_dict самого класса. И, соответственно, когда мы добавляем/удаляем/меняем атрибуты экземпляра класса, мы меняем их, по факту, в __shared_dict.
    Если всё равно не понятно, то запустите код ниже. Он делает, по сути, тоже самое.
    a = [1,2,3]
    b = a
    c = a
    b[1] = 'ай'
    c[0] = 'ой'
    print(a)
    print(b)
    print(c)

  • @Dayplaylist
    @Dayplaylist 2 года назад +4

    Я думаю может пригодиться если надо что-то сразу бэкапить😌 либо когда требуется создавать клоны , полезный материал

  • @sashaperdunov2209
    @sashaperdunov2209 Год назад +2

    Серёга, ты просто красавчик

  • @andredru4278
    @andredru4278 2 месяца назад +1

    Спасибо. Очень интересно.

  • @aleksandrsemenov1764
    @aleksandrsemenov1764 2 года назад +3

    Присоединяюсь к очереди за паттернами =)

  • @pullya66
    @pullya66 2 года назад +1

    отлично, спасибо

  • @Insidepointg
    @Insidepointg 7 месяцев назад +5

    я вроде и понял и не понял суть паттерна.
    Ведь мы же можем создать атрибуты класса типо MIN_COORD и MAX _COORD, и через классметод прописать их изменение, тогда для всех объектов класса. также будут общие одинаковые данные, которые будут меняться для всех

    • @user-eu8qc3mr9j
      @user-eu8qc3mr9j 5 месяцев назад +1

      Пример использования. Если несколько пользователей работают с программой и вносят измененя, например, в базу данных и нужно, что эти измененя учитывались при дальнейшей работе. Например у меня есть БД товаров с остатками и несколько пользователей продают эти товары. Мне нужно, что бы после того, как пользователь 1 продал 1шт какого-то товара, остальные пользователи (все) видели, что на остатке уже 99, а не 100, чтобы не продать несуществующий товар.

    • @user-de3op9hs4p
      @user-de3op9hs4p 3 месяца назад

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

  • @ISAWER1
    @ISAWER1 10 месяцев назад +1

    лайк и комментарий в поддержку канала.

  • @jamjam3337
    @jamjam3337 Год назад +1

    спасибо!

  • @Developer_python_
    @Developer_python_ Год назад

    Прикольно)

  • @ibrahimoglu
    @ibrahimoglu 2 года назад +2

    👍

  • @user-et4if5gs8z
    @user-et4if5gs8z 2 года назад +1

    прикольно

  • @tbassir9076
    @tbassir9076 10 месяцев назад +1

    Как всегда респектище! С другой стороны, если этот метод нигде не применяется, то какой в нём смысл? И ещё, хотелось бы слышать от Вас одну вещь, которую Вы не озвучиваете ни в одном своём ролике: что к примеру данный метод применяется в написании таких то программ, а вот этот метод применяется вот для для этого и так далее. Потому, что выучив язык надо определиться какую область программирования(а не решение задач) дальше изучать, а это новый курс, на основе пройденного.

  • @abdulloakramov7941
    @abdulloakramov7941 10 месяцев назад +1

    👍👍

  • @ivanstereotekkofficial5353
    @ivanstereotekkofficial5353 2 года назад +4

    Спасибо! Расскажите про вложенные(внутренние) классы пожалуйста.

  • @nadyashaymardanova6000
    @nadyashaymardanova6000 Год назад +1

    ❣️

  • @SELYAVINNICK
    @SELYAVINNICK 2 года назад +2

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

    • @selfedu_rus
      @selfedu_rus  2 года назад

      уже делаю, скоро будет! )

    • @mslq
      @mslq Год назад

      У меня есть задача, если интересно, по теме, но с осложнениями, в одном из коментов, как вы любите. ))

  • @bernardsoul8936
    @bernardsoul8936 Месяц назад +1

    А чем это отличается от того, когда мы на прошлых уроках переопределяли метод __new__?

  • @Knight_2017
    @Knight_2017 2 года назад +6

    Для чего может использоваться данный паттерн или в каких задачах проявляются его сильные стороны?

  • @EntireMusic
    @EntireMusic Год назад +1

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

  • @origami5334
    @origami5334 Год назад +3

    Тут есть пару вопросов,1-как вы раньше упоминали если переменная существует в изначальном классе,то экземпляры класса наследуют ее в виде ссылки,а если мы эту переменную хотим изменить то она локально создается внутри экземпляра ,так вот не является ли self.__dict__ локальной переменной для каждого экземпляра,мне просто не очень понятно почему вы к th2 id присвоили 3 и почему то значение локальной переменной которая находится в локальной переменной __dict__ поменялось и у других экземпляров.тут под __dict__ я подразумеваю __shared_attrs,изначально shared_attr ведь переменная класса,которая наследуется в экземпляры,а присваивая th2.id =3 вы по сути создаете локальную переменную __shared_attrs внутри экземпляра,вместо ссылки из основного класса и в нее уже добавляете новый атрибут id=3

    • @origami5334
      @origami5334 Год назад +5

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

    • @antonivanov3830
      @antonivanov3830 9 месяцев назад

      теперь остаётся узнать, почему это работает именно так)

    • @thunderboy2208
      @thunderboy2208 4 месяца назад

      ​@@antonivanov3830 потому что словарь изменяемый тип и мы от всех экземпляров ссылаемся на один и тот же словарь __shared_attrs, и поэтому, когда мы изменяем __dict__ какого либо экземпляра, то мы изменяем и __shared_attrs, а на него ссылаются и остальные экземпляры тоже

  • @duke007x3
    @duke007x3 2 года назад

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

    • @selfedu_rus
      @selfedu_rus  2 года назад +3

      коллекция __dict__ у всех объектов одна и та же

  • @konkotaro
    @konkotaro 2 года назад +1

    Все очень круто, но у меня есть вопрос: это же можно делать когда мы создадим Singlton. Будет ли какая-то разница? Или через Singlton это не уместно делать, но принцип тот же: ссылается на одно и то же. Спасибо.

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      Это отличается от Singleton, т.к. здесь нет запрета но создание множества экземпляров, просто у всех у них единые локальные свойства, но пространство имен, все же свое, независимое.

    • @andreistasevich9894
      @andreistasevich9894 2 года назад +1

      @@selfedu_rus а с точки зрения многопоточности есть разница, с чем работать?
      В случае синглтона потоки будут обращаться к одной памяти, где хранится объект. В случае монопоточности - к одному участку памяти, где хранятся свойства. Вроде нет особой разницы. Это как я представляю.
      Мои знания о многопоточности практически нулевые, так как я только азы изучил

  • @MrSmallChe
    @MrSmallChe 2 года назад

    Не понял , чем это отличается от статических атрибутов класса?

  • @sidorovich21101986
    @sidorovich21101986 2 года назад +2

    А в многопоточных приложениях такое моносостояние сохраняется? К примеру, в одном потоке мы считываем данные (например, из консольного приложения), а в другом потоке мы обрабатываем их.
    А то я для хранения данных в много-потоках вместо этого использую статические свойства класса (не создавая экземпляры) или статические геттеры и сеттеры. Если что, я в Python не профессионал, это моё хобби.

    • @selfedu_rus
      @selfedu_rus  2 года назад

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

  • @user-qd5bg5sw7k
    @user-qd5bg5sw7k Год назад

    Чтобы "self.__shared_attrs" нельзя было переобпределить нам его нужно инкапсулировать тем плагином, который закрывает возможность изменения свойства класса или через дескрипторы, верно?

  • @Fenix102RUS
    @Fenix102RUS Месяц назад +1

    У меня не работает моно... создаются как будто два разных экземпляра все равно

  • @teacherit5840
    @teacherit5840 Год назад

    А куда изначально добавляется новый созданный атрибут в __shared_attr или в про-во имен экземпляра? Просто в коде мы пишем self.__dict__ = self.__shared_attrs , это равно пр-во имен экземпляра равно словарю shared? Как тогда это влияет на другие экземпляры?

    • @selfedu_rus
      @selfedu_rus  Год назад

      в пространстве имен класса

  • @sgst555
    @sgst555 8 месяцев назад +1

    блин у меня чуть голова не взорвалась в понимании механизма работы моносостояния, но так и не понял (( как же меняется словарь класса??
    PS через полтора часа похоже понял - вся фишка в одинаковой ссылке на словарь.... но писец как не очевидно для новичков

  • @user-dk9hr2op7p
    @user-dk9hr2op7p 2 года назад +1

    Получается создать атрибуты отличные от других экземпляров классов уже не получится? А что при наследовании?

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      Да, не получится. И при наследовании также, т.к. мы на уровне экземпляров классов работаем

  • @andrewskylone1052
    @andrewskylone1052 Год назад +1

    А можно реализовать этот паттерн просто переопределивши метод __setattr__, чтобы он устанавливал все атрибуты в окружение класса переданного экземпляра?
    def __setattr__(self, key, value):
    setattr(self.__class__, key, value)

    • @selfedu_rus
      @selfedu_rus  Год назад

      Можно, но, по моему вариант в видео элегантнее.

  • @migorpresents8991
    @migorpresents8991 9 месяцев назад

    А как так получается, что редактируя атрибут одного объекта задеваются остальные экземпляры? Да, в этот раз мы инициализировали объекты с помощью одного словаря, но что это изменило?

    • @selfedu_rus
      @selfedu_rus  8 месяцев назад

      Локальные атрибуты классов определяются словарем __dict__. Если он един для всех объектов, то и значения также едины.

  • @workpony2028
    @workpony2028 2 года назад +1

    Скажите пожалуйста, почему self._shared_attrs вообще работает? ThreadData.__shared_attrs я проверил тоже работает и я понимаю почему, но почему работает с .self???

    • @alexanderg9089
      @alexanderg9089 2 года назад +1

      есть объяснение в предыдущих уроках, магия вседозволенности в Python. Через ThreadData вы обращаетесь к атрибутам класса, через self как к атрибутам класса так и к атрибутам экземпляра класса.

    • @workpony2028
      @workpony2028 2 года назад

      @@alexanderg9089 вот я и подумал, разве при инициализации __dict__ через self.__shared_attrs не будет создаваться пустой словарь в экземпляре класса? Оказалось, что не будет. И это привело меня в недоумение. Единственное объяснение - класс object проверяет наличие словаря с таким именем в базовом классе, если не находит в экземпляре и только если и там тоже нет - создает. Но корректнее, как по мне, пользоваться вызовом "BasicClass.__somearg", особенно в потоках.

  • @CrazyHandMaker
    @CrazyHandMaker 2 года назад +1

    А почему новый атрибут attr_new добавился в словарь __shared_attrs?

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      Потому что __shared_attrs ссылается на коллекцию __dict__ объекта класса.

    • @CrazyHandMaker
      @CrazyHandMaker 2 года назад

      @@selfedu_rus Но ведь
      self.__dict__ = self.__shared_attrs
      тут __dict__ ссылается на __shared_attrs.
      А что сама __shared_attrs ссылается на что-либо в коде нет. Не пойму, в чём магия?

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      @@CrazyHandMaker ну, да, __dict__ на __shared_attrs, в итоге обе ссылки ведут на один и тот же словарь

    • @alexanderg9089
      @alexanderg9089 2 года назад

      @@CrazyHandMaker попробуйте представить что _dict_ и __shared_attrs это всего лишь навсего имена переменных, как ссылки, на одну и туже область памяти. Примитивно, но смысл тот же, мне помогает понимать.

    • @CrazyHandMaker
      @CrazyHandMaker 2 года назад

      @@alexanderg9089 Ну по факту так и есть. Но где это указывается?

  • @andreychernykh256
    @andreychernykh256 2 года назад +2

    пришел сегодня сертификат по Вашему курсу. в нем написано что я закончил с отличием хотя я прошел только 39% . странно

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      ошибка с моей стороны была, поправил, ну сертификат у вас уже останется, пользуйтесь :)

  • @BaDiTaRaKaN
    @BaDiTaRaKaN 2 года назад

    Я вот только не понял, почему ссылка идет не на cls (cls.__shared_attrs), а на сам объект.

    • @selfedu_rus
      @selfedu_rus  2 года назад

      Словарь __shared_attrs определен в самом классе и общий для всех объектов.

  • @tigrangasparyan8008
    @tigrangasparyan8008 4 месяца назад +1

    Кто может сказать, можно ли создать моносостояние, но каким-то образом поменять атрибуты одного из объектов, не меняя атрибуты других?

    • @MevErex
      @MevErex 2 месяца назад +1

      Не знаю зачем тебе это, но конечно можно. Главное помнить, что после этого объект станет полностью независим от других.
      import copy
      class Node:
      __coords = {"x": 0, "y": 0}
      def __init__(self) -> None:
      self.__dict__ = self.__coords
      def free_state(self):
      self.__dict__ = copy.deepcopy(self.__dict__)
      def linked_state(self):
      self.__dict__ = Node.__coords
      a = Node()
      b = Node()
      c = Node()
      a.x = 10
      print(f"b.x = {b.x}, c.x = {c.x}")
      c.free_state() # С этого момента с - независимый объект
      a.x = 5
      a.z = 7
      c.y = 2
      print(f"b.__dict__ = {b.__dict__}, c.__dict__ = {c.__dict__}")
      c.linked_state() # С этого момента с - обратно связанный объект
      print(f"b.__dict__ = {b.__dict__}, c.__dict__ = {c.__dict__}")
      Результат:
      ---------------------------------------------
      b.x = 10, c.x = 10
      b.__dict__ = {'x': 5, 'y': 0, 'z': 7}, c.__dict__ = {'x': 10, 'y': 2}
      b.__dict__ = {'x': 5, 'y': 0, 'z': 7}, c.__dict__ = {'x': 5, 'y': 0, 'z': 7}

  • @ShadowStormlq5mwdasd
    @ShadowStormlq5mwdasd 2 года назад +1

    То есть получается у всех экземпляров класса будет одно и то же значение?

    • @selfedu_rus
      @selfedu_rus  2 года назад

      да

    • @mslq
      @mslq Год назад

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

  • @user-uz8sb2es7i
    @user-uz8sb2es7i 11 месяцев назад +1

    разные ссылки ведущие к одному к экземпляру

  • @nadyashaymardanova6000
    @nadyashaymardanova6000 Год назад

    🏃

  • @zakirovio
    @zakirovio 11 месяцев назад +1

    это тонкий намек на то что в Python выполняется только один поток?))

  • @avazart614
    @avazart614 2 года назад

    Зачем __dict___ ?
    class ThreadData:
    name = 'thread1'
    data = {}
    id = 1
    будет ровно тоже самое
    Еще более странно зачем оно потребовалось в контектсте использования потоков где наоборот нужно губокое копрование что бы не попортить данные.

    • @bocik2854
      @bocik2854 2 года назад

      Потому что при попытке изменения переменных name,id и т.д. через экземпляр класса(к примеру, th1.id = 5), внутри локальных областей экземплярлв будут созданы локальные переменные, а атрибуты класса не изменятся

  • @user-qd5bg5sw7k
    @user-qd5bg5sw7k Год назад +2

    И очень занимательный факт получается. Если сравнивать объекты th1 is th2 то это будет False, а если сравнить th1.__dict__ is th2.__dict__ будет True

    • @darya_matv
      @darya_matv 8 месяцев назад +1

      Потому что в классе не реализован магический метод, отвечающий за сравнение

  • @SLSRPPRO
    @SLSRPPRO 2 года назад +2

    что такое паттерны ? зачем они ?

    • @selfedu_rus
      @selfedu_rus  2 года назад

      паттерн (схема, шаблон) построения архитектур больших программ

  • @user-zm5nd9vu7n
    @user-zm5nd9vu7n 2 месяца назад +1

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

    • @MevErex
      @MevErex 2 месяца назад +1

      Я уже собирался накать простыню текста, но кто-то опередил, и рассказал суть. Упорядочи комментарии "Сначала новые" и увидишь ответ на свой вопрос на два комментария ниже. Если кратко, то когда A и B - это списки, словари, множества или объекты, то операция A = B *не копирует* B в A. Это ссылки, и A теперь ссылается на ту же область памяти, что и B.
      В нашем случае у всех новых экземпляров объектов пространство имен "не свое", т.е. __dict__ будет ссылаться на один и тот же словарь __shared_attrs основного класса. Если будет непонятно после прочтения коммента ниже, то могу потом подробнее объяснить.

    • @user-zm5nd9vu7n
      @user-zm5nd9vu7n 2 месяца назад

      Понял кажется, то есть по сути при создании в одном экземпляре нового атрибута, этот атрибут и его значение запишутся в шаддер атт, так же как бы записалось в __дикт__ ?

    • @user-zm5nd9vu7n
      @user-zm5nd9vu7n 2 месяца назад

      ​@@MevErexспасибо за ответ)

    • @MevErex
      @MevErex 2 месяца назад

      Да, все верно поняли. Типичная ошибка многих новичков, которые после кода:
      A = {"name": "Masha", "age": 18}
      B = A
      B["name"] = "Olya"
      print(A["name"])
      получают результат:
      Olya
      типа что за магия, я не трогал А вообще, как так. Более того, можно вынести это все вообще в отдельную переменную вне объектов и изменять только ёё, с тем же результатом.
      C = ThreadData._ThreadData__shared_attrs
      A = ThreadData()
      B = ThreadData()
      C["port"] = 8080
      Теперь во всех экземплярах класса A и B появится новый атрибут port, а в основном классе ThreadData в словаре __shared_attrs добавится ключ "port" со значением 8080.

  • @andreychernykh256
    @andreychernykh256 2 года назад +4

    хотелось бы несколько задач под каждым видео, до выхода курса не дотерплю

    • @selfedu_rus
      @selfedu_rus  2 года назад +1

      можно взять из предыдущего круса

  • @user-qj6tk5fw9p
    @user-qj6tk5fw9p 10 месяцев назад +1

    python не перестает меня удивлять, protected и private атрибуты есть, но толку от этих модификаторов доступа нет, так как их можно легко обойти. Как же я скучаю по С++, в котором если какой то метод private, то он private, и доступа к нему из вне класса нет как ты не крути, все просто и понятно не то что в якобы простом python

    • @selfedu_rus
      @selfedu_rus  10 месяцев назад +2

      на самом деле и в С++ можно напрямую к приватным обратиться, но это уже будет извращением ))

  • @user-et4if5gs8z
    @user-et4if5gs8z 2 года назад +1

    прикольно

  • @ms77grz
    @ms77grz Год назад +1

    👍👍