
Introspection в Python – это способность программы исследовать свои собственные объекты во время выполнения. Она позволяет получать информацию о типах объектов, их атрибутах, методах и структуре без необходимости обращаться к исходному коду.
Основные инструменты introspection включают функции type(), dir(), id() и модуль inspect. type() возвращает класс объекта, dir() перечисляет доступные атрибуты и методы, а id() позволяет получить уникальный идентификатор объекта в памяти.
Модуль inspect расширяет возможности introspection. С его помощью можно получать сигнатуры функций, списки аргументов, исходный код функций и классов, проверять, является ли объект модулем, классом или функцией. Это особенно полезно для динамической генерации документации, отладки и тестирования.
Правильное использование introspection повышает гибкость кода. Например, с его помощью можно создавать универсальные функции, которые работают с объектами разных типов, или автоматически регистрировать методы и свойства классов без ручного вмешательства.
В Python introspection не ограничена стандартными инструментами: комбинация getattr(), hasattr() и setattr() позволяет изменять поведение объектов во время выполнения, что открывает возможности для метапрограммирования и создания адаптивных библиотек.
Как узнать тип объекта с помощью introspection
В Python определить тип объекта можно с помощью встроенной функции type(). Она возвращает точный класс объекта, что особенно полезно при работе с динамической типизацией.
Пример использования:
num = 42
print(type(num)) # <class 'int'>
Для проверки принадлежности объекта к конкретному классу или его наследникам применяется функция isinstance(). Она позволяет безопасно выполнять операции, зависящие от типа объекта, без необходимости явного сравнения с type().
Пример проверки:
if isinstance(num, int):
print("Целое число")
Иногда требуется сравнить точный тип объекта, исключая наследников. В таких случаях используют type(obj) is SomeClass. Это гарантирует точное соответствие, что важно при строгих проверках.
Для динамического анализа типов и получения информации о базовых классах объекта применяют .__class__ и .__bases__. Первый возвращает класс объекта, второй – кортеж базовых классов.
Пример с базовыми классами:
print(num.__class__) # <class 'int'>
print(int.__bases__) # (<class 'object'>,)
Использование introspection для определения типа объектов повышает гибкость кода, снижает риск ошибок и позволяет строить универсальные функции и библиотеки, работающие с разными типами данных. Основной подход – комбинировать type() для точного соответствия и isinstance() для проверки наследования.
Проверка наличия атрибутов и методов у объектов
В Python проверка наличия атрибутов и методов у объектов выполняется с помощью функции hasattr(obj, name). Она возвращает True, если объект obj содержит атрибут или метод с именем name, и False в противном случае. Например, hasattr(list(), "append") вернёт True, а hasattr(list(), "remove_item") – False.
Для динамического доступа к атрибутам используется getattr(obj, name[, default]). Если атрибут существует, возвращается его значение; если нет, можно задать значение по умолчанию, чтобы избежать ошибки AttributeError. Пример: value = getattr(obj, "attr_name", None).
С помощью setattr(obj, name, value) можно создавать или изменять атрибуты на лету, что удобно для генерации объектов с динамическими свойствами. delattr(obj, name) позволяет удалять атрибуты программно.
Для проверки наличия метода можно использовать callable(getattr(obj, "method_name", None)). Если результат True, метод доступен для вызова. Этот подход безопасен, так как getattr возвращает None, если метод отсутствует, и не вызывает исключение.
Функции dir(obj) и vars(obj) предоставляют списки доступных атрибутов и методов. dir возвращает полный набор, включая унаследованные, а vars – только атрибуты текущего объекта. Их использование полезно при отладке или документировании структуры объекта.
Практическое правило: при работе с внешними объектами сначала проверяйте наличие атрибутов через hasattr, затем используйте getattr для безопасного доступа и callable для проверки вызова методов. Это снижает вероятность неожиданных ошибок и упрощает динамическое взаимодействие с объектами.
Получение списка всех методов и свойств объекта

Для фильтрации только методов можно использовать функцию callable() в комбинации с dir(). Пример:
[attr for attr in dir(obj) if callable(getattr(obj, attr))] – возвращает список методов объекта obj.
Свойства и переменные объекта доступны через проверку, что атрибут не является вызываемым:
[attr for attr in dir(obj) if not callable(getattr(obj, attr))]. Это полезно для динамического анализа состояния объекта без знания его структуры заранее.
Для глубокого introspection можно использовать модуль inspect. Функция inspect.getmembers(obj) возвращает пары (имя, значение) всех атрибутов. Дополнительно inspect.isfunction и inspect.ismethod позволяют точечно фильтровать функции и методы.
При работе с классами полезно разделять методы экземпляра и класса. dir(cls) покажет все атрибуты класса, а комбинация getattr(cls, attr) и inspect.ismethoddescriptor позволяет идентифицировать дескрипторы и свойства.
from pprint import pprint; pprint(dir(obj)).
Таким образом, сочетание dir(), callable() и inspect позволяет получить полный и структурированный список методов и свойств любого объекта в Python.
Определение базовых и дочерних классов объекта

Для анализа иерархии классов в Python используется introspection с функциями type() и issubclass(). Метод type(obj) возвращает непосредственный класс объекта, позволяя точно определить его тип:
пример:
class A: pass
class B(A): pass
x = B()
print(type(x)) # <class 'B'>
Чтобы получить список базовых классов объекта, применяется атрибут __bases__ у класса:
пример:
print(B.__bases__) # (<class 'A'>,)
Для проверки, является ли класс дочерним по отношению к другому, используют issubclass():
пример:
print(issubclass(B, A)) # True
print(issubclass(A, B)) # False
Если требуется полностью пройтись по иерархии наследования, применяют mro() (Method Resolution Order):
пример:
print(B.mro()) # [<class 'B'>, <class 'A'>, <class 'object'>]
Практическая рекомендация: для анализа сложных иерархий используйте сочетание type(), __bases__ и mro(), чтобы корректно определить все уровни наследования и избежать ошибок при проверках типа объектов.
Извлечение документации и сигнатуры функций
В Python introspection позволяет получать информацию о функциях без их изменения. Для извлечения документации используется атрибут __doc__. Например, print(len.__doc__) выведет описание встроенной функции len.
Для получения сигнатуры функций применяют модуль inspect. Основной метод – inspect.signature(func), который возвращает объект Signature с параметрами и их типами, если они аннотированы.
Пример извлечения сигнатуры и документации:
| Функция | Документация | Сигнатура |
|---|---|---|
| sorted | Return a new sorted list from the items in iterable. |
(iterable, /, *, key=None, reverse=False) |
| sum | Sums start and the items of an iterable from left to right and returns the total. |
(iterable, start=0) |
Для анализа пользовательских функций удобно создавать универсальную функцию:
import inspect
def describe(func):
doc = func.__doc__ or "Документация отсутствует"
sig = str(inspect.signature(func))
return {"doc": doc, "signature": sig}
Результат работы describe позволяет автоматически формировать справочные таблицы и использовать данные для логирования или генерации документации.
При использовании аннотаций типов сигнатура сохраняет информацию о типах параметров, что облегчает статический анализ и автодополнение в IDE.
Использование introspection для динамического вызова методов

Пример базового динамического вызова метода:
class Calculator:
def add(self, x, y):
return x + y
calc = Calculator()
method_name = "add"
if hasattr(calc, method_name):
method = getattr(calc, method_name)
result = method(5, 3)
print(result) # 8
Рекомендации при работе с динамическими вызовами:
- Всегда проверяйте существование метода с помощью
hasattr, чтобы избежатьAttributeError. - Используйте
callable(), если требуется убедиться, что атрибут действительно можно вызвать. - Для передачи аргументов применяйте кортежи и словари вместе с
*argsи**kwargs:
method_name = "add"
args = (10, 7)
if hasattr(calc, method_name):
method = getattr(calc, method_name)
if callable(method):
result = method(*args)
print(result) # 17
Иногда полезно строить динамическую цепочку вызовов:
methods = ["add", "subtract"]
values = [(5, 3), (10, 4)]
for name, args in zip(methods, values):
if hasattr(calc, name):
func = getattr(calc, name)
if callable(func):
print(func(*args))
Дополнительно introspection помогает интегрировать плагины или расширения без изменения исходного кода:
- Используйте
dir(object)для получения всех методов объекта. - Фильтруйте методы по префиксу или регулярным выражениям для автоматического вызова нужных функций.
Такой подход делает код гибким, снижает жесткую связку между компонентами и позволяет реализовывать динамическую логику вызова функций в зависимости от состояния программы.
Вопрос-ответ:
Что такое introspection в Python?
Introspection в Python — это возможность программы узнавать структуру объектов во время выполнения. С помощью этой функции можно получать информацию о типе объекта, его атрибутах, методах и документации. Это удобно для анализа кода, динамической проверки и тестирования без необходимости заранее знать точную реализацию объектов.
Какие встроенные функции помогают выполнять introspection?
Python предоставляет несколько инструментов для introspection. Например, функция type() показывает тип объекта, dir() возвращает список доступных атрибутов и методов, id() — уникальный идентификатор объекта, getattr() и hasattr() позволяют получать или проверять существование конкретного атрибута. Эти функции часто применяются вместе для изучения поведения и свойств объектов.
Как можно узнать, какие методы доступны у объекта?
Для этого применяется функция dir(). Она возвращает список всех атрибутов и методов объекта, включая встроенные. Если требуется получить только методы, можно дополнительно фильтровать элементы, проверяя, является ли каждый элемент вызываемым через callable(). Это помогает определить, какие действия можно выполнять с объектом без обращения к документации.
Можно ли использовать introspection для функций и классов?
Да, introspection применим как к функциям, так и к классам. Например, __doc__ позволяет получить строку документации, __name__ — имя функции или класса. С помощью inspect модуля можно узнать список аргументов функции, проверить, является ли объект классом или функцией, а также изучать наследование и структуры классов. Это упрощает анализ сложного кода.
Какие практические задачи можно решать с помощью introspection?
С помощью introspection можно создавать отладочные утилиты, автоматические тесты, динамически вызывать методы или проверять типы данных в рантайме. Например, фреймворки для тестирования или ORM используют introspection для анализа структуры классов и автоматического формирования запросов. Она также помогает изучать чужой код, определять доступные методы и атрибуты без необходимости читать всю реализацию.
