Python пример класса с атрибутами

Классы и объекты. Атрибуты классов и объектов

Меня зовут Сергей Балакирев и на этом занятии мы с вами узнаем, как в Python определять классы, создавать объекты (экземпляры) этих классов, а также добавлять и удалять их атрибуты (то есть, данные).

Предположим, мы хотим определить класс для хранения координат точек на плоскости. Для начала я его запишу без какого-либо содержимого, только имя класса Point и все:

Здесь оператор pass указывает, что мы в классе ничего не определяем. Также обратите внимание, что в соответствии со стандартом PEP8 имя класса принято записывать с заглавной буквы. И, конечно же, называть так, чтобы оно отражало суть этого класса. В дальнейшем я буду придерживаться этого правила.

Итак, у нас получилось простейшее определение класса с именем Point. Но в таком виде он не особо полезен. Поэтому я пропишу в нем два атрибута: color – цвет точек; circle – радиус точек:

class Point: color = 'red' circle = 2

Обратите внимание, переменные внутри класса обычно называются атрибутами класса или его свойствами. Я буду в дальнейшем использовать эту терминологию. Теперь в нашем классе есть два атрибута color и circle. Но, как правильно воспринимать эту конструкцию? Фактически, сам класс образует пространство имен, в данном случае с именем Point, в котором находятся две переменные color и circle. И мы можем обращаться к ним, используя синтаксис для пространства имен, например:

или для считывания значения:

(В консольном режиме увидим значение 2). А чтобы увидеть все атрибуты класса можно обратиться к специальной коллекции __dict__:

Читайте также:  Масштабируемое фоновое изображение css

Здесь отображается множество служебных встроенных атрибутов и среди них есть два наших: color и circle.

Теперь сделаем следующий шаг и создадим экземпляры этого класса. В нашем случае для создания объекта класса Point достаточно после его имени прописать круглые скобки:

Смотрите, справа на панели в Python Console у нас появилась переменная a, через которую доступны два атрибута класса: color и circle.

Давайте создадим еще один объект этого класса:

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

С помощью функции type мы можем посмотреть тип данных для переменных a или b:

Видим, что это класс Point. Эту принадлежность можно проверить, например, так:

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

Во-первых, объекты a и b образуют свое пространство имен – пространство имен экземпляров класса и, во-вторых, не содержат никаких собственных атрибутов. Свойства color и circle принадлежат непосредственно классу Point и находятся в нем, а объекты a и b лишь имеют ссылки на эти атрибуты класса. Поэтому я не случайно называю их именно атрибутами класса, подчеркивая этот факт. То есть, атрибуты класса – общие для всех его экземпляров. И мы можем легко в этом убедиться. Давайте изменим значение свойства circle на 1:

И в обоих объектах это свойство стало равно 1. Мало того, если посмотреть коллекцию __dict__ у объектов:

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

Но, если мы выполним присваивание, например:

То, смотрите, в объекте a свойство color стало ‘green’, а в b – прежнее. Почему? Дело в том, что мы здесь через переменную a обращаемся к пространству имен уже экземпляра класса и оператор присваивания в Python создает новую переменную, если она отсутствует в текущей локальной области видимости, то есть, создается атрибут color уже непосредственно в объекте a:

Мы можем в этом убедиться, если отобразим коллекцию __dict__ этого объекта:

То есть, мы с вами создали локальное свойство в объекте a. Этот момент нужно очень хорошо знать и понимать. На этом принципе в Python построено формирование атрибутов классов и локальных атрибутов их экземпляров.

Добавление и удаление атрибутов класса

Кстати, по аналогии, мы можем создавать новые атрибуты и в классе, например, так:

Или то же самое можно сделать с помощью специальной функции:

Она создает новый атрибут в указанном пространстве имен (в данном случае в классе Point) с заданным значением. Если эту функцию применить к уже существующему атрибуту:

setattr(Point, 'type_pt', 'square')

то оно будет изменено на новое значение.

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

Но, при обращении к несуществующему атрибуту класса, например:

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

Здесь третий аргумент – возвращаемое значение, если атрибут не будет найден. Эту же функцию можно вызвать и с двумя аргументами:

Но тогда также будет сгенерирована ошибка при отсутствии указанного атрибута. Иначе:

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

Наконец, мы можем удалять любые атрибуты из класса. Сделать это можно, по крайней мере, двумя способами. Первый – это воспользоваться оператором del:

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

Она возвращает True, если атрибут найден и False – в противном случае.

Также удалить атрибут можно с помощью функции:

Она работает аналогично оператору del.

И, обратите внимание, удаление атрибутов выполняется только в текущем пространстве имен. Например, если попытаться удалить свойство color из объекта b:

то получим ошибку, т.к. в объекте b не своих локальных свойств и удалять здесь в общем то нечего. А вот в объекте a есть свое свойство color, которое мы с вами добавляли:

Смотрите, после удаления локального свойства color в объекте a становится доступным атрибут color класса Point с другим значение ‘black’. И это логично, т.к. если свойство не обнаруживается в локальной области, то поиск продолжается в следующей (внешней) области видимости. А это (для объекта a) класс Point. Вот этот момент также следует хорошо понимать при работе с локальными свойствами объектов и атрибутами класса.

Атрибуты экземпляров классов

Теперь, когда мы знаем, как создаются атрибуты, вернемся к нашей задаче формирования объектов точек на плоскости. Мы полагаем, что атрибуты color и circle класса Point – это общие данные для всех объектов этого класса. А вот координаты точек должны принадлежать его экземплярам. Поэтому для объектов a и b мы определим локальные свойства x и y:

a.x = 1 a.y = 2 b.x = 10 b.y = 20

То есть, свойства x, y будут существовать непосредственно в объектах, но не в самом классе Point:

В результате, каждый объект представляет точку с независимыми координатами на плоскости. А цвет и их размер – общие данные для всех объектов.

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

class Point: "Класс для представления координат точек на плоскости" color = 'red' circle = 2

В результате, специальная переменная:

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

Заключение

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

Видео по теме

Концепция ООП простыми словами

#1. Классы и объекты. Атрибуты классов и объектов

#2. Методы классов. Параметр self

#3. Инициализатор __init__ и финализатор __del__

#4. Магический метод __new__. Пример паттерна Singleton

#5. Методы класса (classmethod) и статические методы (staticmethod)

#6. Режимы доступа public, private, protected. Сеттеры и геттеры

#7. Магические методы __setattr__, __getattribute__, __getattr__ и __delattr__

#9. Свойства property. Декоратор @property

#10. Пример использования объектов property

#11. Дескрипторы (data descriptor и non-data descriptor)

#12. Магический метод __call__. Функторы и классы-декораторы

#13. Магические методы __str__, __repr__, __len__, __abs__

#14 Магические методы __add__, __sub__, __mul__, __truediv__

#15. Методы сравнений __eq__, __ne__, __lt__, __gt__ и другие

#16. Магические методы __eq__ и __hash__

#17. Магический метод __bool__ определения правдивости объектов

#18. Магические методы __getitem__, __setitem__ и __delitem__

#19. Магические методы __iter__ и __next__

#20. Наследование в объектно-ориентированном программировании

#21. Функция issubclass(). Наследование от встроенных типов и от object

#22. Наследование. Функция super() и делегирование

#23. Наследование. Атрибуты private и protected

#24. Полиморфизм и абстрактные методы

#25. Множественное наследование

#27. Как работает __slots__ с property и при наследовании

#28. Введение в обработку исключений. Блоки try / except

#29. Обработка исключений. Блоки finally и else

#30. Распространение исключений (propagation exceptions)

#31. Инструкция raise и пользовательские исключения

#32. Менеджеры контекстов. Оператор with

#34. Метаклассы. Объект type

#35. Пользовательские метаклассы. Параметр metaclass

#36. Метаклассы в API ORM Django

#37. Введение в Python Data Classes (часть 1)

#38. Введение в Python Data Classes (часть 2)

#39. Python Data Classes при наследовании

© 2023 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта

Источник

Оцените статью