Любая пусто это пусто в которой параметрами являются атрибуты объектов
ООП: атрибуты и методы
Два главных слова любого программиста в ООП. Знай их, люби их, говори правильно.
Продолжаем цикл статей об основах объектно-ориентированного программирования. Сегодня говорим о двух важных словах в ООП: атрибутах и методах. Это основа лексикона ООП, поэтому нужно знать.
Краткое содержание предыдущих частей:
Теперь нырнём в атрибуты и методы.
Атрибуты
Атрибут — это переменная, связанная с объектом или классом. Грубо говоря, если я хочу, чтобы у объекта «Пользователь» появилась фамилия, я должен сделать пользователю атрибут «Фамилия».
Для программистов: у класса есть атрибуты, свойства и поля. В зависимости от языка программирования эти три параметра могут означать одно и то же, а могут различаться. В этой статье мы разбираем академический подход к структуре класса вида «атрибут — значение».
Возьмём в качестве примера метафору — производство телефонов. У нас есть класс «Смартфон» — некий абстрактный смартфон, по лекалам которого изготавливают конкретные объекты-смартфоны.
У класса «Смартфон» могут быть такие атрибуты:
Это у нас будут атрибуты класса «Смартфон». Они могут принимать конкретные значения: камеры могут быть разных моделей, память может быть 64 или 256 гигабайт, а батарейка — 2500 мАч или 3500 мАч.
Когда мы задаём атрибут для класса, мы как будто настраиваем производственную линию: «Тут у нас будет станок по установке камер, там — по вклеиванию батареи». Когда мы задали класс с определёнными атрибутами, все объекты, произведённые из этого класса, будут появляться на свет с этими атрибутами.
Методы
Методы — это то, как можно взаимодействовать с атрибутами, узнавать и менять их значения. Рассмотрим их на том же прошлом примере про класс мобильника. Вот какие действия можно совершать:
Получается, что методы отвечают за то, чтобы можно было взаимодействовать с классом. Чаще всего они отвечают за то, что можно сделать с атрибутами
Если посмотреть на список, можно заметить, что почти все методы доступны для выполнения извне — позвонить, сделать фото, посмотреть погоду и так далее. Это значит, что это открытые методы (public) — их может вызывать и работать с ними кто угодно: как пользователь, так и другие программы для своих нужд.
Но два других метода из списка — особенные: обработать HDR-фото и поймать сигнал сети. Их нельзя запустить напрямую, их вызывает операционная система, когда ей это нужно. Это значит, что это закрытые (private) методы, и они доступны только внутри самого класса. Если классу понадобится что-то обработать внутри себя, он ими воспользуется, а другие не смогут этого сделать.
Ещё есть защищённые (protected) методы. Их пока нет в наших примерах, но мы до них обязательно дойдём.
атрибут объекта
3.1 атрибут объекта: Элемент данных, представляющий определенную характеристику объекта (информационного, информационно-интеллектуального, предметного) и имеющий имя и значение.
Смотреть что такое “атрибут объекта” в других словарях:
атрибут объекта (сети и системы связи) — Поле, категория или значение данных, которые совместно с другими атрибутами задают сервисы или значения данных, относящиеся к данной функции и характеристикам объекта. [ГОСТ Р 54325 2011 (IEC/TS 61850 2:2003)] EN object attribute field or a… … Справочник технического переводчика
атрибут — 3.2 атрибут (attribute): Свойство или характеристика объекта, которые могут быть определены количественно или качественно вручную или автоматическими средствами. [ИСО/МЭК 15939:2007] Источник … Словарь-справочник терминов нормативно-технической документации
АТРИБУТ — (от лат. attribuo придаю, наделяю) необходимое, существенное свойство объекта. Напр., А. материальных вещей протяженность, вес, цвет и т.п. Уже Аристотель отличал постоянные А. от акциденций случайных, преходящих состояний. В дальнейшем под А.… … Философская энциклопедия
Атрибут — в базах данных имя или структура поля записи. Атрибут характеризует размер или тип информации, содержащейся в поле. По английски: Attribute См. также: Реляционная модель данных Финансовый словарь Финам. Атрибут Атрибут в диаграммах сущность связь … Финансовый словарь
АТРИБУТ — [лат. attributum приданное] 1) филос. неотъемлемое, существенное свойство объекта (напр., движение а. материи); 2) лингв. то же, что определение; 3) существенный признак, постоянное свойство чего л., неотъемлемая принадлежность предмета. Словарь… … Словарь иностранных слов русского языка
атрибут — а, м. attribut m., лат. attributum. 1. Необходимое, существенное, неотъемлемое свойство объекта или явления в отличие от случайных, преходящих его состояний. БАС 2. Сорная рожь оказалась распадающеся при созревании на колоски, опадающие на землю … Исторический словарь галлицизмов русского языка
атрибут (пространственного объекта) — Непозиционная характеристика пространственного объекта с ее качественным или количественным значением. [ГОСТ Р 52438 2005] Тематики географические информационные системы … Справочник технического переводчика
АТРИБУТ — (от латинского attribuo придаю, наделяю), необходимое, существенное, неотъемлемое свойство объекта (например, в философии Спинозы атрибут субстанции протяжение и мышление) … Современная энциклопедия
АТРИБУТ — (от лат. attribuo придаю наделяю). 1) необходимое, существенное, неотъемлемое свойство объекта (напр., атрибут материи в философии движение)2)] В языкознании то же, что определение … Большой Энциклопедический словарь
Атрибут — (лат. аttribuo – қосып беремін, үлестіремін, atributum – қосып жіберілген – присовокупленное) 1) философияда – объектінің онсыз бар бола алмайтын да және ойланылмайтын да ажыратылмас қасиеті (неотъемлемое свойство объекта, без которго он не может … Философиялық терминдердің сөздігі
Атрибуты объектов
Объекты и классы
Объектная модель системы
Объектная модель описывает структуру объектов, составляющих систему, их атрибуты, операции, взаимосвязи с другими объектами. В объектной модели должны быть отражены те понятия и объекты реального мира, которые важны для разрабатываемой системы. В объектной модели отражается прежде всего прагматика разрабатываемой системы, что выражается в использовании терминологии прикладной области, связанной с использованием разрабатываемой системы.
По определению будем называть объектом понятие, абстракцию или любую вещь с четко очерченными границами, имеющую смысл в контексте рассматриваемой прикладной проблемы. Введение объектов преследует две цели:
Примеры объектов: форточка, Банк “Империал”, Петр Сидоров, дело № 7461, сберкнижка и т.д.
Все объекты одного и того же класса характеризуются одинаковыми наборами атрибутов. Однако объединение объектов в классы определяется не наборами атрибутов, а семантикой. Так, например, объекты конюшня и лошадь могут иметь одинаковые атрибуты: цена и возраст. При этом они могут относиться к одному классу, если рассматриваются в задаче просто как товар, либо к разным классам, что более естественно.
Рис. 2.1. Пример класса и объекта этого класса
Объединение объектов в классы позволяет ввести в задачу абстракцию и рассмотреть ее в более общей постановке. Класс имеет имя (например лошадь), которое относится ко всем объектам этого класса. Кроме того, в классе вводятся имена атрибутов, которые определены для объектов. В этом смысле описание класса аналогично описанию типа структуры (записи); при этом каждый объект имеет тот же смысл, что и экземпляр структуры (переменная или константа соответствующего типа). Пример класса и объекта этого класса приведен на рисунке 2.1.
Среди атрибутов различаются постоянные атрибуты (константы) и переменные атрибуты. Постоянные атрибуты характеризуют объект в его классе (например, номер счета, категория, имя человека и т.п.). Текущие значения переменных атрибутов характеризуют текущее состояние объекта (например, баланс счета, возраст человека и т.п.); изменяя значения этих атрибутов, мы изменяем состояние объекта.
Пользовательские атрибуты в Python
__dict__
В примере описан класс StuffHolder с одним атрибутом stuff, который, наследуют оба его экземпляра. Добавление объекту b атрибута b_stuff, никак не отражается на a.
Посмотрим на __dict__ всех действующих лиц:
(У класса StuffHolder в __dict__ хранится объект класса dict_proxy с кучей разного барахла, на которое пока не нужно обращать внимание).
Ни у a ни у b в __dict__ нет атрибута stuff, не найдя его там, механизм поиска ищет его в __dict__ класса (StuffHolder), успешно находит и возвращает значение, присвоенное ему в классе. Ссылка на класс хранится в атрибуте __class__ объекта.
Поиск атрибута происходит во время выполнения, так что даже после создания экземпляров, все изменения в __dict__ класса отразятся в них:
В случае присваивания значения атрибуту экземпляра, изменяется только __dict__ экземпляра, то есть значение в __dict__ класса остаётся неизменным (в случае, если значением атрибута класса не является data descriptor):
Если имена атрибутов в классе и экземпляре совпадают, интерпретатор при поиске значения выдаст значение экземпляра (в случае, если значением атрибута класса не является data descriptor):
По большому счёту это всё, что можно сказать про __dict__. Это хранилище атрибутов, определённых пользователем. Поиск в нём производится во время выполнения и при поиске учитывается __dict__ класса объекта и базовых классов. Также важно знать, что есть несколько способов переопределить это поведение. Одним из них является великий и могучий Дескриптор!
Дескрипторы
С простыми типами в качестве значений атрибутов пока всё ясно. Посмотрим, как ведёт себя функция в тех же условиях:
WTF!? Спросите вы… возможно. Я бы спросил. Чем функция в этом случае отличается от того, что мы уже видели? Ответ прост: методом __get__.
Этот метод переопределяет механизм получения значения атрибута func экземпляра fh, а объект, который реализует этот метод непереводимо называется non-data descriptor.
Дескриптор — это объект, доступ к которому через атрибут переопределён методами в дескриптор протоколе:
Дескрипторы данных
Рассмотрим повнимательней дескриптор данных:
Стоит обратить внимание, что вызов DataHolder.data передаёт в метод __get__ None вместо экземпляра класса.
Проверим утверждение о том, что у дата дескрипторов преимущество перед записями в __dict__ экземпляра:
Так и есть, запись в __dict__ экземпляра игнорируется, если в __dict__ класса экземпляра (или его базового класса) существует запись с тем же именем и значением — дескриптором данных.
Ещё один важный момент. Если изменить значение атрибута с дескриптором через класс, никаких методов дескриптора вызвано не будет, значение изменится в __dict__ класса как если бы это был обычный атрибут:
Дескрипторы не данных
Пример дескриптора не данных:
Его поведение слегка отличается от того, что вытворял дата-дескриптор. При попытке присвоить значение атрибуту non_data, оно записалось в __dict__ экземпляра, скрыв таким образом дескриптор, который хранится в __dict__ класса.
Примеры использования
Дескрипторы это мощный инструмент, позволяющий контролировать доступ к атрибутам экземпляра класса. Один из примеров их использования — функции, при вызове через экземпляр они становятся методами (см. пример выше). Также распространённый способ применения дескрипторов — создание свойства (property). Под свойством я подразумеваю некое значение, характеризующее состояние объекта, доступ к которому управляется с помощью специальных методов (геттеров, сеттеров). Создать свойство просто с помощью дескриптора:
Или можно воспользоваться встроенным классом property, он представляет собой дескриптор данных. Код, представленный выше можно переписать следующим образом:
В обоих случаях мы получим одинаковое поведение:
Важно знать, что property всегда является дескриптором данных. Если в его конструктор не передать какую либо из функций (геттер, сеттер или делитер), при попытке выполнить над атрибутом соответствующее действие — выкинется AttributeError.
__getattr__(), __setattr__(), __delattr__() и __getattribute__()
Если нужно определить поведение какого-либо объекта как атрибута, следует использовать дескрипторы (например property). Тоже справедливо для семейства объектов (например функций). Ещё один способ повлиять на доступ к атрибутам: методы __getattr__(), __setattr__(), __delattr__() и __getattribute__(). В отличие от дескрипторов их следует определять для объекта, содержащего атрибуты и вызываются они при доступе к любому атрибуту этого объекта.
__getattr__(self, name) будет вызван в случае, если запрашиваемый атрибут не найден обычным механизмом (в __dict__ экземпляра, класса и т.д.):
__getattribute__(self, name) будет вызван при попытке получить значение атрибута. Если этот метод переопределён, стандартный механизм поиска значения атрибута не будет задействован. Следует иметь ввиду, что вызов специальных методов (например __len__(), __str__()) через встроенные функции или неявный вызов через синтаксис языка осуществляется в обход __getattribute__().
__setattr__(self, name, value) будет вызван при попытке установить значение атрибута экземпляра. Аналогично __getattribute__(), если этот метод переопределён, стандартный механизм установки значения не будет задействован:
__delattr__(self, name) — аналогичен __setattr__(), но используется при удалении атрибута.
При переопределении __getattribute__(), __setattr__() и __delattr__() следует иметь ввиду, что стандартный способ получения доступа к атрибутам можно вызвать через object:
__slots__
… Я боялся что изменения в системе классов плохо повлияют на производительность. В частности, чтобы дескрипторы данных работали корректно, все манипуляции атрибутами объекта начинались с проверки __dict__ класса на то, что этот атрибут является дескриптором данных…
На случай, если пользователи разочаруются ухудшением производительности, заботливые разработчики python придумали __slots__.
Наличие __slots__ ограничивает возможные имена атрибутов объекта теми, которые там указаны. Также, так как все имена атрибутов теперь заранее известны, снимает необходимость создавать __dict__ экземпляра.
Оказалось, что опасения Guido не оправдались, но к тому времени, как это стало ясно, было уже слишком поздно. К тому же, использование __slots__ действительно может увеличить производительность, особенно уменьшив количество используемой памяти при создании множества небольших объектов.
Заключение
Доступ к атрибутом в python можно контролировать огромным количеством способов. Каждый из них решает свою задачу, а вместе они подходят практически под любой мыслимый сценарий использования объекта. Эти механизмы — основа гибкости языка, наряду с множественным наследованием, метаклассами и прочими вкусностями. У меня ушло некоторое время на то, чтобы разобраться, понять и, главное, принять это множество вариантов работы атрибутов. На первый взгляд оно показалось слегка избыточным и не особенно логичным, но, учитывая, что в ежедневном программировании это редко пригодиться, приятно иметь в своём арсенале такие мощные инструменты.
Надеюсь, и вам эта статья прояснила парочку моментов, до которых руки не доходили разобраться. И теперь, с огнём в глазах и уверенностью в Точке, вы напишите огромное количество наичистейшего, читаемого и устойчивого к изменениям требований кода! Ну или комментарий.
Атрибуты (C#)
Атрибуты предоставляют мощное средство для связывания метаданных или декларативной информации с кодом (сборки, типы, методы, свойства и т. д.). Связав атрибут связан с сущностью программы, вы можете проверять этот атрибут во время выполнения, используя технику отражения. Подробнее см. в разделе Отражение (C#).
Атрибуты имеют следующие свойства.
Использование атрибутов
Атрибуты можно использовать почти в любых объявлениях, но для каждого атрибута можно ограничить типы объявлений, в которых он является допустимым. Чтобы указать атрибут на C#, поместите имя атрибута в квадратных скобках ([]) над объявлением сущности, к которой он применяется.
В этом примере атрибут SerializableAttribute используется для применения определенной характеристики к классу:
Метод с атрибутом DllImportAttribute объявляется следующим образом:
В объявлении можно разместить несколько атрибутов, как показано в следующем примере:
Некоторые атрибуты можно указать для одной сущности более одного раза. Пример такого многократно используемого атрибута — ConditionalAttribute:
Параметры атрибутов
Многие атрибуты имеют параметры, которые могут быть позиционными, неименованными или именованными. Позиционные параметры должны указываться в определенном порядке и не могут опускаться. Именованные параметры являются необязательными и могут указываться в любом порядке. Сначала указываются позиционные параметры. Например, эти три атрибута являются эквивалентными:
Первый параметр (имя библиотеки DLL) является позиционным и всегда располагается первым, остальные параметры являются именованными. В этом примере оба именованных параметра имеют значение по умолчанию (false), и мы можем их опустить. Позиционные параметры соответствуют параметрам конструктора атрибутов. Именованные (или необязательные) параметры соответствуют свойствам или полям атрибута. Сведения о значениях параметров по умолчанию указываются в документации по каждому отдельному атрибуту.
Дополнительные сведения о разрешенных типах параметров см. в разделе Атрибуты в спецификации языка C#.
Целевые объекты атрибутов
Целевой объект атрибута — это сущность, к которой применяется атрибут. Например, атрибут можно применить к классу, отдельному методу или ко всей сборке. По умолчанию атрибут применяется к тому элементу, который следует за ним. Но у вас есть возможность явным образом указать, например, что атрибут применяется к методу, параметру или возвращаемому значению.
Чтобы явным образом определить целевой объект атрибута, используйте следующий синтаксис:
Возможные значения target перечислены в следующей таблице.
| Целевое значение | Применение |
|---|---|
| assembly | Вся сборка |
| module | Модуль текущей сборки |
| field | Поле в классе или структуре |
| event | событие |
| method | Метод либо методы доступа к свойствам get и set |
| param | Параметры метода или параметры метода доступа set |
| property | Свойство. |
| return | Возвращаемое значение метода, индексатора свойства или метода доступа к свойствам get |
| type | Структура, класс, интерфейс, перечисление или делегат |
Следующий пример демонстрирует, как применить атрибуты к сборкам и модулям. Дополнительные сведения см. в разделе Общие атрибуты (C#).
В следующем примере показано, как применять атрибуты к методам, параметрам и возвращаемым значениям методов в C#.
Популярные методы применения атрибутов
В следующем списке перечислены несколько распространенных применений для атрибутов.
Связанные разделы
Дополнительные сведения можно найти в разделе
