#26. Коллекция __slots__ | Объектно-ориентированное программирование Python

Поделиться
HTML-код
  • Опубликовано: 27 сен 2024
  • Курс по Python ООП: stepik.org/a/1...
    Зачем нужна коллекция _slots_ в классах языка Python. Преимущества при ее использовании.
    Плейлист по Python ООП: • Объектно-ориентированн...
    Инфо-сайт: proproprogs.ru...
    Telegram-канал: t.me/python_se...

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

  • @WhispInTheDark
    @WhispInTheDark 2 года назад +17

    Спасибо огромное за Ваш труд! Ваш канал точно лучший вариант для учебы в ру сегменте

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

    Традиционное спасибо Сергею за отличный краткий и понятный урок!

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

    Какая классная штука!

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

    Очень доступно,как для младенцев)

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

    Спасибо. Интересно. Вроде понятно. Надо попробовать.

  • @expollux
    @expollux 2 года назад +19

    2:42 Про недопустимость "z" - полностью согласен

  • @cryptokrupt
    @cryptokrupt Год назад +6

    Сделал замер времени для обоих классов как по инструкции, но класс Point2D со слотс в итоге дольше работал, чем Point без без слотс....

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

    Благодарю!

  • @НикитаПавлов-э8г
    @НикитаПавлов-э8г 2 года назад +2

    С новим роком

  • @gayratsaidakhmedov5451
    @gayratsaidakhmedov5451 7 месяцев назад +1

    спасибо

  • @jaksonmillka
    @jaksonmillka 7 дней назад

    Урок #26 = Пройден
    Узнал о __slots__, и его функциональности. На самом деле, в каких то изолированных классах, думаю, он будет полезен

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

    👍

  • @Dmitry-ug1zq
    @Dmitry-ug1zq 2 года назад +5

    Хотелось бы уточнить, после подсчета используемой памяти мы считаем только сколько занял сам объект класса, но не добавляем объем занимаемой памяти __slots__.
    Правильнее ли было, например, a.__sizeof__() + a.__slots__.__sizeof__() ? Поскольку slots тоже хранит атрибуты, не считать занимаемую им память неправильно

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

      print(pt.__sizeof__() + pt.__dict__.__sizeof__()) # -> 120 байт
      print(pt2.__sizeof__() + pt2.__slots__.__sizeof__()) # -> 72 байта
      Но следует учитывать, что __slots__ - атрибут уровня класса (не копируется в экземпляры).
      В общем, с __slots__ эффективнее по памяти.

    • @РустамРаджабов-ц3м
      @РустамРаджабов-ц3м 6 месяцев назад

      а у меня без слотс 304 байта вышло,
      хотя все как видео @@nevadawolf3040

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

    Сергей, спасибо за труд. Остался вопрос. В чем необходимость создавать коллекцию __slots__, если, чтобы ограничить количество возможных создаваемых переменных экземпляра, можно переопределять метод __setattr__?
    Что-то по типу:
    def __setattr_(self, key, value):
    if key == 'z': # любая переменная
    raise AttributeError
    Вопрос не относится к проблеме затрачиваемой памяти для каждого экземпляра класса.

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

      этот код не будет работать, будет RecursionError

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

      @@thenoteasy все будет работать, даже показывали такой пример в уроке с __setattr__ , просто логичнее перебрать все разрешенные, а не все запрещенные. Разрешенных то всяко меньше будет)

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

    Можете после этого курса, создать курс по асинхронности в питоне?)

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

      Мне нужен по машинному обучению для студентов - буду его делать.

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

      @@selfedu_rus Сергей у вас уже есть курс по машинному обучению?

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

      @@nomadicus77 Да, см. на канале плейлист "Машинное обучение"

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

    Здравствуйте, Сергей! Спасибо за урок. Возникли вопросы, при создании класса выделяется память именно под него?. Ведь он может иметь свои атрибуты, также о какой именно памяти идется при вызове __sizeof__ на экземпляре класса, другими словами, зачем выделять память под экземпляр класса, если все его атрибуты хранятся в __dict__. В чем разница между памятью выделяемой под __dict__ и для экземпляра класса, __dict__ это же фактически пространство имен, если мы через него можем менять локальные атрибуты?

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

      Хороший вопрос. Я, как то, об этом не задумывался. Сейчас сделал небольшой тест:
      class Point:
      def __init__(self, x, y):
      self.x = x
      self.y = y
      p = Point(1, 2)
      print(p.__sizeof__())
      print(p.__dict__.__sizeof__())
      print(sys.getsizeof(p))
      print(sys.getsizeof(Point))
      Здесь getsizeof() функция определения объема занимаемой объектом памяти. Получается класс Point занимает 1064 байт, а p значительно меньше. Я не знаю, как в деталях происходит хранение и представление объектов и отдельно классов. Наверное это нужно погуглить ))

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

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

  • @dubinin_s
    @dubinin_s 2 года назад +7

    Огромное спасибо за видео.
    Но у меня все же остались вопросы.
    Первый вопрос по поводу памяти: при использовании __slots__ коллекция __dict__ отсутствует, но зато появляется коллекция __slots__(извиняюсь за тавтологию) ==> память = pt.__sizeof__() + pt.__slots__.__sizeof__(), или нет?
    Второй вопрос по поводу самой коллекции __slots__: __slots__ задаем как кортеж(неизменяемый объект), но никто не мешает задать его списком и тогда мы сможем добавить в коллекцию __slots__ еще один элемент pt.__slots__.append('s'). Но вот беда, элемент добавляется, но тем не менее ему нельзя присвоить значение pt.s = 'что-то' (AttributeError: 'Point3D' object has no attribute 's'). Вот это мне не понятно, элемент в коллекции появился, а сделать с ним ничего нельзя. как так?
    Попробую сам ответить на второй вопрос.
    __slots__ свойство класса которое не копируется в экземпляр, экземпляр имеет лишь ссылку на это свойство. По всей видимости строчка pt.__slots__.append('s') создает __slots__ в экземпляре (только вот где она сохраняется ведь __dict__ нет???), при попытки записать чего то pt.s = 'что-то' и поскольку __dict__ в экземпляре нет, автоматически берется __slots__ из класса, отсюда и AttributeError: 'Point3D' object has no attribute 's'.

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

      Вообщем-то в первом вопросе понял где не прав))))

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

      Как такое объяснить)))
      class Point3D:
      __slots__ = ['x', 'y', 'z']
      def __init__(self, x , y, z):
      self.x = x
      self.y = y
      self.z = z

      pt1 = Point3D(10, 20, 30)
      pt1.__slots__.append('s')
      print(id(pt1.__slots__), id(Point3D.__slots__), pt1.__slots__, Point3D.__slots__, sep='
      ')
      _____________________________
      140379690590688
      140379690590688
      ['x', 'y', 'z', 's']
      ['x', 'y', 'z', 's']
      _____________________________
      pt1.s = 100
      _______________________
      AttributeError: 'Point3D' object has no attribute 's'

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

      @@dubinin_s атрибуту __slots__ можно присвоить любой итерируемый объект, интерпритатор Python помещает его в кортежеподобную структуру в каждом экземпляре. Что при этом происходит мне неизвестно, но я читал, что у __slots __ много подводных камней.

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

      @@n0rmaLman спасибо и на таком ответе))

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

      Если не до конца понятно, пока пропустите. Понадобится - разберетесь. Так во всем )

  • @evenfreefire400
    @evenfreefire400 11 месяцев назад +2

    как я понял, в версии 3.11 теперь можно создавать локальные аттрибуты, даже если они не указаны в коллекции __slots__, то есть эта коллекция теперь используется только для экономии памяти?

    • @MrSasuke1337
      @MrSasuke1337 11 месяцев назад

      Прикинь, у меня вообще __slots__ ускорял работу только при третьей попытки, т1 работал быстрее т2, но я думаю все из-за моего слабого процессора на Ноутбуке, Pentium silver

    • @MrSasuke1337
      @MrSasuke1337 11 месяцев назад

      У меня тож версия 3.11, у тебя __slots__ ускорял работу локальных атрибутов?

    • @user-test-testov
      @user-test-testov 14 дней назад

      Прежде всего коллеция _slots__ запрещает создавать другие атрибуты. Иногда это полезно.

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

    Большое спасибо за ваши уроки! Сначала я понимал процентов 40-60, но с кааждым новым уроком начинаю лучше понимать и предыдущие темы

  • @Pr.A.M.
    @Pr.A.M. Год назад +1

    здравствуйте а где 25 урок ?

  • @ДмитрийСергеев-л6г
    @ДмитрийСергеев-л6г 2 года назад +3

    Сергей, спасибо вам за ваш труд!!!

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

    Спасибо за урок, с каждой темой понимаю все больше и больше

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

    используя __slots__ далеко не факт, что будет экономиться память. например, если оба класса будут содержать по 8 переменных, то экземпляр класса Point2d уже будет занимать больше памяти, чем экземпляр класса Point.

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

      коллекция __slots__ - атрибут уровня класса и она не копируется в экземпляры, поэтому ее размер учитывать не нужно

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

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

  • @андрейхоменко-и5я
    @андрейхоменко-и5я 2 года назад +1

    Как всегда спасибо. Сергей, если не трудно подтвердите мои умозаключения по данному уроку. Метод __slots__ предлагает способ для оптимизации скорости приложения посредством его внедрения в классы. Экземпляры, которых в рамках общего алгоритма не учавствуют или не требуют манипуляций над локальными свойствами этого объекта.

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

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

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

    Я объявил __slots__ через метод класса, и он почему-то не работает. Как быть?

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

      slots должен быть атрибутом класса, а не его экземпляра

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

    Почему перезалив?