
При анализе кода на Python часто требуется понять, какие данные и методы уже определены в классе. Это нужно при отладке, работе с чужими библиотеками, генерации документации или динамической обработке объектов. Язык Python предоставляет несколько встроенных механизмов, позволяющих получить список атрибутов класса без чтения его исходного кода.
В статье рассматриваются способы получения атрибутов через dir(), __dict__, а также методы фильтрации служебных имён, унаследованных элементов и функций. Отдельное внимание уделяется ситуациям, когда необходимо получить только пользовательские поля или сравнить набор атрибутов базового и дочернего класса.
Все примеры ориентированы на прикладные задачи: проверка структуры класса во время выполнения, поиск нужного свойства по имени, анализ API и автоматизация проверок. Материал подходит для использования в реальном коде без дополнительных библиотек.
Получение атрибутов класса с помощью dir()
Функция dir() возвращает список имён, связанных с объектом класса на момент вызова. При передаче класса в dir() результатом будет отсортированный список строк, включающий пользовательские атрибуты, методы, а также унаследованные элементы и служебные имена.
Типовой сценарий использования – быстрый анализ доступных атрибутов без обращения к __dict__ или исходному коду. Это удобно при интерактивной работе, отладке или проверке сторонних классов, когда структура заранее неизвестна.
Для практического применения список, полученный через dir(), обычно фильтруют. Чаще всего исключают имена, начинающиеся и заканчивающиеся двойным подчёркиванием, а также элементы, не относящиеся к логике класса. Такой подход позволяет выделить пользовательские поля и методы без ручного перебора.
Следует помнить, что dir() возвращает только имена атрибутов, без их значений. Если требуется получить связанные данные или функции, необходимо дополнительно использовать getattr() или обращаться к __dict__ класса.
Наиболее распространённый признак служебных атрибутов – двойное подчёркивание в начале и в конце имени. Такие элементы отвечают за внутреннее устройство класса, работу операторов, доступ к метаданным и не предназначены для прямого использования в прикладном коде.
При фильтрации списка атрибутов на практике применяются простые правила: исключение имён с шаблоном __*, отбор только тех элементов, которые присутствуют в __dict__ класса, а также проверка принадлежности атрибута текущему классу, а не базовым.
Ниже приведены типовые категории атрибутов, которые чаще всего исключаются из итогового списка:
| Категория | Пример имени | Причина исключения |
|---|---|---|
| Специальные атрибуты Python | __init__, __str__ | Используются интерпретатором |
| Метаданные класса | __module__, __doc__ | Не описывают поведение класса |
| Унаследованные элементы | __hash__, __eq__ | Приходят из базовых классов |
Если требуется получить только пользовательские атрибуты, обычно ориентируются на содержимое __dict__ и дополнительно отбрасывают вызываемые объекты. Такой подход позволяет сформировать список полей, заданных разработчиком, без шума из внутренних деталей реализации.
Разница между атрибутами класса и атрибутами экземпляра
Атрибуты класса задаются в теле класса и доступны всем экземплярам. Они хранятся в ClassName.__dict__ и используются для общих данных или методов.
- Общие для всех объектов класса
- Изменение через класс отражается на всех экземплярах без переопределения
- Используются для хранения констант и общих функций
- Не зависят от создания экземпляра
Атрибуты экземпляра создаются после инициализации объекта, обычно в __init__. Они сохраняются в instance.__dict__ и принадлежат конкретному объекту.
- Индивидуальны для каждого экземпляра
- Могут перекрывать одноимённые атрибуты класса
- Изменение не влияет на другие объекты
- Используются для хранения состояния конкретного экземпляра
При поиске атрибута Python сначала проверяет словарь экземпляра, затем словарь класса и базовых классов. Для точного анализа структуры класса рекомендуется отдельно просматривать ClassName.__dict__ и instance.__dict__, не полагаясь на объединённый список dir().
Для получения списка только пользовательских атрибутов класса рекомендуется работать с __dict__, исключая служебные имена и унаследованные элементы. Такой подход позволяет отделить логические поля и методы, созданные разработчиком, от внутренних атрибутов Python.
Простая фильтрация выполняется по следующим правилам:
- Имена, начинающиеся и заканчивающиеся двойным подчёркиванием, игнорируются
- Имена, присутствующие только в __dict__ класса, учитываются как пользовательские
- Методы и функции можно оставить или отфильтровать в зависимости от задачи
Пример практического применения:
- Создание динамической документации по классу
- Автоматическая проверка структуры класса в тестах
- Сбор данных для сериализации объектов без включения служебных полей
Получение атрибутов и их значений через __dict__
Словарь __dict__ содержит реальные пары ключ-значение для атрибутов класса или экземпляра. В отличие от dir(), он позволяет получить не только имена, но и текущие значения, что важно при анализе состояния объектов и проверке логики класса.
При работе с ClassName.__dict__ возвращаются все атрибуты, определённые в теле класса, включая методы и свойства. Для исключения служебных элементов рекомендуется фильтровать имена с двойным подчёркиванием.
Пример использования __dict__ для получения атрибутов и их значений:
| Атрибут | Значение | Описание |
|---|---|---|
| name | ‘UAZ’ | Пользовательское поле класса |
| wheels | 4 | Стандартное значение для всех экземпляров |
| __module__ | ‘vehicles’ | Служебный атрибут, содержит имя модуля |
Для анализа состояния экземпляра используется instance.__dict__. Он содержит только атрибуты конкретного объекта, что позволяет отделить пользовательские данные от общих атрибутов класса и унаследованных элементов.
Для определения метода используют встроенную функцию callable(). Она проверяет, можно ли вызвать объект как функцию:
- Если callable(attr) возвращает True, объект является методом или функцией
- Если False, объект – поле данных или свойство
Пример подхода:
- Проход по ключам ClassName.__dict__
- Проверка значения через callable()
- Разделение на методы и обычные атрибуты
Отдельное внимание стоит уделить статическим и классовым методам. Они обернуты в staticmethod и classmethod, но callable() также возвращает True, что позволяет включить их в список методов без дополнительных проверок.
Проверка наличия конкретного атрибута в классе
Для проверки существования атрибута в классе используется встроенная функция hasattr(). Она принимает два аргумента: объект класса и имя проверяемого атрибута в виде строки. Функция возвращает True, если атрибут присутствует, и False в противном случае.
Пример применения:
- Проверка поля данных или метода перед доступом через getattr()
- Динамическая обработка атрибутов при работе с неизвестными классами
- Фильтрация списка атрибутов для документации или тестирования
Важно учитывать, что hasattr() проверяет и атрибуты, унаследованные от базовых классов. Для точной проверки наличия атрибута только в конкретном классе используется ClassName.__dict__:
- Если имя присутствует в ClassName.__dict__, атрибут определён именно в этом классе
- Если имя отсутствует, оно может быть унаследовано или отсутствовать вовсе
Сравнение атрибутов родительского и дочернего классов

При наследовании дочерний класс получает все атрибуты родительского класса, включая методы и поля данных. Для анализа структуры полезно различать унаследованные атрибуты и добавленные или переопределённые в дочернем классе.
Основные подходы к сравнению:
- Сравнение словарей ParentClass.__dict__ и ChildClass.__dict__
- Выделение новых атрибутов, отсутствующих в родительском классе
- Идентификация переопределённых методов и полей
Пример практической проверки:
- Собрать список атрибутов родительского класса через ParentClass.__dict__.keys()
- Собрать список атрибутов дочернего класса через ChildClass.__dict__.keys()
- Разделить элементы на три категории:
- Унаследованные атрибуты
- Добавленные в дочернем классе
- Переопределённые атрибуты
Такой метод позволяет создавать точные отчёты по структуре классов, выявлять конфликты имён и планировать изменения в иерархии наследования. Для динамических проверок удобно комбинировать dir() и __dict__, чтобы учитывать как унаследованные, так и локальные атрибуты.
Вопрос-ответ:
Как получить список всех атрибутов класса в Python?
Для вывода всех атрибутов класса используется функция dir(). Она возвращает отсортированный список строк, включающий имена методов, полей данных, служебные элементы и унаследованные атрибуты. Если нужно выделить только пользовательские атрибуты, рекомендуется дополнительно фильтровать имена с двойным подчёркиванием и проверять принадлежность к словарю __dict__ класса.
В чём разница между атрибутами класса и атрибутами экземпляра?
Атрибуты класса создаются в теле класса и доступны всем его объектам. Изменение значения атрибута класса через класс влияет на все экземпляры, если они не переопределили его локально. Атрибуты экземпляра создаются при инициализации объекта и принадлежат конкретному объекту, изменения не затрагивают другие экземпляры. Для точного анализа структуры рекомендуется отдельно просматривать ClassName.__dict__ и instance.__dict__.
Как вывести только пользовательские атрибуты класса без служебных элементов?
Используется словарь ClassName.__dict__, который содержит пары имя-значение всех атрибутов класса. Для фильтрации исключают имена с двойным подчёркиванием и, при необходимости, методы. Проход по ключам __dict__ позволяет сформировать список атрибутов, созданных разработчиком, без внутренних служебных элементов Python.
Можно ли определить методы класса при выводе атрибутов?
Да, для этого проверяют, является ли объект вызываемым с помощью функции callable(). Она возвращает True для методов, функций, статических и классовых методов. Применение этой проверки к значениям в ClassName.__dict__ позволяет отделять методы от обычных полей данных и формировать отдельный список функциональных элементов класса.
Как проверить наличие конкретного атрибута в классе?
Для проверки используют функцию hasattr(ClassName, ‘attribute_name’), которая возвращает True, если атрибут существует, и False, если нет. Чтобы убедиться, что атрибут определён именно в текущем классе, проверяют наличие имени в ClassName.__dict__. Этот метод позволяет отличать локальные атрибуты от унаследованных.
Как отличить методы класса от полей данных при выводе списка атрибутов?
Для разделения методов и полей данных используют функцию callable(). Если значение атрибута возвращает True при проверке callable(attr), значит, это метод, функция, статический или классовый метод. Поля данных при этом возвращают False. Такой подход помогает формировать отдельные списки для анализа структуры класса и для документации.
Можно ли получить значения всех атрибутов класса вместе с их именами?
Да, для этого используют словарь ClassName.__dict__. Он содержит пары ключ-значение для всех атрибутов класса, включая методы и свойства. Чтобы исключить служебные элементы, фильтруют имена с двойным подчёркиванием. Такой метод позволяет получить актуальные значения атрибутов для проверки состояния класса или автоматической генерации отчётов.
