inspect.md
1> **Источник:** https://python-all.ru/3.4/library/inspect.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 29.12. [`inspect`](https://python-all.ru/3.4/library/inspect.html#module-inspect) – Инспекция активных объектов89**Исходный код:** [Lib/inspect.py](https://python-all.ru/src/3.4/Lib/inspect.py)1011---1213Модуль [`inspect`](https://python-all.ru/3.4/library/inspect.html#module-inspect) предоставляет несколько полезных функций для получения информации об активных объектах, таких как модули, классы, методы, функции, трассировки стека, объекты фреймов и объекты кода. Например, с его помощью можно просмотреть содержимое класса, получить исходный код метода, извлечь и отформатировать список аргументов функции или получить всю информацию, необходимую для отображения подробной трассировки стека.1415Этот модуль предоставляет четыре основных вида сервисов: проверка типов, получение исходного кода, инспекция классов и функций, а также анализ стека интерпретатора.1617## 29.12.1. Типы и члены1819Функция [`getmembers()`](https://python-all.ru/3.4/library/inspect.html#inspect.getmembers) извлекает члены объекта, такого как класс или модуль. Шестнадцать функций, имена которых начинаются с «is», в основном предоставляются как удобные варианты для второго аргумента [`getmembers()`](https://python-all.ru/3.4/library/inspect.html#inspect.getmembers). Они также помогают определить, когда можно ожидать следующие специальные атрибуты:2021| Тип | Атрибут | Описание |22| --- | --- | --- |23| модуль | doc | строка документации |24| | file | filename (отсутствует для встроенных модулей) |25| класс | doc | строка документации |26| | name | имя, под которым был определён этот класс |27| | qualname | полное имя |28| | module | имя модуля, в котором был определён этот класс |29| метод | doc | строка документации |30| | name | имя, под которым был определён этот метод |31| | qualname | полное имя |32| | func | объект функции, содержащий реализацию метода |33| | self | экземпляр, к которому привязан этот метод, или `None` |34| функция | doc | строка документации |35| | name | имя, под которым была определена эта функция |36| | qualname | полное имя |37| | code | объект кода, содержащий скомпилированную функцию [*байткод*](https://python-all.ru/3.4/glossary.html#term-bytecode) |38| | defaults | кортеж значений по умолчанию для позиционных или именованных параметров |39| | kwdefaults | отображение значений по умолчанию для параметров, доступных только по ключевым словам |40| | globals | глобальное пространство имён, в котором была определена эта функция |41| трассировка | tb\_frame | объект фрейма на этом уровне |42| | tb\_lasti | индекс последней предпринятой инструкции в байткоде |43| | tb\_lineno | текущий номер строки в исходном коде Python |44| | tb\_next | следующий внутренний объект traceback (вызванный на этом уровне) |45| фрейм | f\_back | следующий внешний объект фрейма (вызывающий этот фрейм) |46| | f\_builtins | пространство имён builtins, видимое этим фреймом |47| | f\_code | объект кода, выполняющийся в этом фрейме |48| | f\_globals | глобальное пространство имён, видимое этим фреймом |49| | f\_lasti | индекс последней предпринятой инструкции в байткоде |50| | f\_lineno | текущий номер строки в исходном коде Python |51| | f\_locals | локальное пространство имён, видимое этим фреймом |52| | f\_restricted | 0 или 1, если фрейм находится в ограниченном режиме выполнения |53| | f\_trace | функция трассировки для этого фрейма, или `None` |54| код | co\_argcount | количество аргументов (не включая \* или \*\* args) |55| | co\_code | строка сырого скомпилированного байткода |56| | co\_consts | кортеж констант, используемых в байткоде |57| | co\_filename | имя файла, в котором был создан этот объект кода |58| | co\_firstlineno | номер первой строки в исходном коде Python |59| | co\_flags | битовая маска: 1=оптимизировано `\|` 2=новые локальные `\|` 4=\*arg `\|` 8=\*\*arg |60| | co\_lnotab | кодированное отображение номеров строк на индексы байт-кода |61| | co\_name | имя, с которым был определён этот объект кода |62| | co\_names | кортеж имён локальных переменных |63| | co\_nlocals | количество локальных переменных |64| | co\_stacksize | требуемый размер стека виртуальной машины |65| | co\_varnames | кортеж имён аргументов и локальных переменных |66| встроенный | doc | строка документации |67| | name | исходное имя этой функции или метода |68| | qualname | полное имя |69| | self | экземпляр, к которому привязан метод, или `None` |7071#### `inspect.getmembers(object[, predicate])`7273Возвращает все члены объекта в виде списка пар (имя, значение), отсортированных по имени. Если передан необязательный аргумент *predicate*, включаются только те члены, для которых предикат возвращает истинное значение.7475> **Примечание**76>77> [`getmembers()`](https://python-all.ru/3.4/library/inspect.html#inspect.getmembers) возвращает только атрибуты класса, определённые в метаклассе, если аргумент – класс и эти атрибуты перечислены в пользовательском [`__dir__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__dir__) метакласса.7879#### `inspect.getmoduleinfo(path)`8081Возвращает [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple) `ModuleInfo(name, suffix, mode, module_type)` со значениями, описывающими, как Python будет интерпретировать файл по *path*, если это модуль, или `None`, если он не идентифицируется как модуль. В этом кортеже *name* – имя модуля без имени оборачивающего пакета, *suffix* – конечная часть имени файла (которая может быть не расширением, отделённым точкой), *mode* – режим [`open()`](https://python-all.ru/3.4/library/functions.html#open), который будет использован (`'r'` или `'rb'`), а *module\_type* – целое число, представляющее тип модуля. *module\_type* будет иметь значение, которое можно сравнить с константами, определёнными в модуле [`imp`](https://python-all.ru/3.4/library/imp.html#module-imp); подробнее о типах модулей см. документацию этого модуля.8283Устарело с версии 3.3: Можно проверить суффикс пути к файлу среди поддерживаемых суффиксов, перечисленных в [`importlib.machinery`](https://python-all.ru/3.4/library/importlib.html#module-importlib.machinery), чтобы вывести ту же информацию.8485#### `inspect.getmodulename(path)`8687Возвращает имя модуля, задаваемое файлом *path*, без имён оборачивающих пакетов. Расширение файла проверяется по всем записям из [`importlib.machinery.all_suffixes()`](https://python-all.ru/3.4/library/importlib.html#importlib.machinery.all_suffixes). Если совпадение найдено, возвращается последний компонент пути с удалённым расширением. В противном случае возвращается `None`.8889Note that this function *only* returns a meaningful name for actual Python modules - paths that potentially refer to Python packages will still return `None`.9091Изменено в версии 3.3: Эта функция теперь напрямую основана на [`importlib`](https://python-all.ru/3.4/library/importlib.html#module-importlib), а не на устаревшей [`getmoduleinfo()`](https://python-all.ru/3.4/library/inspect.html#inspect.getmoduleinfo).9293#### `inspect.ismodule(object)`9495Возвращает True, если объект является модулем.9697#### `inspect.isclass(object)`9899Возвращает True, если объект является классом, встроенным или созданным в коде Python.100101#### `inspect.ismethod(object)`102103Возвращает True, если объект является связанным методом, написанным на Python.104105#### `inspect.isfunction(object)`106107Возвращает True, если объект является функцией Python, включая функции, созданные с помощью выражения [*lambda*](https://python-all.ru/3.4/glossary.html#term-lambda).108109#### `inspect.isgeneratorfunction(object)`110111Возвращает True, если объект является функцией-генератором Python.112113#### `inspect.isgenerator(object)`114115Возвращает True, если объект является генератором.116117#### `inspect.istraceback(object)`118119Возвращает True, если объект является трассировкой.120121#### `inspect.isframe(object)`122123Возвращает True, если объект является фреймом.124125#### `inspect.iscode(object)`126127Возвращает True, если объект является кодом.128129#### `inspect.isbuiltin(object)`130131Возвращает True, если объект является встроенной функцией или связанным встроенным методом.132133#### `inspect.isroutine(object)`134135Возвращает True, если объект является пользовательской или встроенной функцией или методом.136137#### `inspect.isabstract(object)`138139Возвращает True, если объект является абстрактным базовым классом.140141#### `inspect.ismethoddescriptor(object)`142143Возвращает true, если объект является дескриптором метода, но не если [`ismethod()`](https://python-all.ru/3.4/library/inspect.html#inspect.ismethod), [`isclass()`](https://python-all.ru/3.4/library/inspect.html#inspect.isclass), [`isfunction()`](https://python-all.ru/3.4/library/inspect.html#inspect.isfunction) или [`isbuiltin()`](https://python-all.ru/3.4/library/inspect.html#inspect.isbuiltin) возвращают true.144145Например, это верно для `int.__add__`. Объект, прошедший этот тест, имеет атрибут `__get__`, но не `__set__`; однако помимо этого набор атрибутов варьируется. [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) обычно разумен, и `__doc__` тоже часто.146147Методы, реализованные через дескрипторы и также проходящие один из других тестов, возвращают false для теста [`ismethoddescriptor()`](https://python-all.ru/3.4/library/inspect.html#inspect.ismethoddescriptor) просто потому, что другие тесты обещают больше – например, можно рассчитывать на наличие атрибута `__func__` (и т.д.), когда объект проходит [`ismethod()`](https://python-all.ru/3.4/library/inspect.html#inspect.ismethod).148149#### `inspect.isdatadescriptor(object)`150151Возвращает True, если объект является дескриптором данных.152153Дескрипторы данных имеют как атрибут `__get__`, так и атрибут `__set__`. Примеры: свойства (определяемые в Python), getsets и members. Последние два определены в C, и для этих типов существуют более специфичные тесты, что надёжно для разных реализаций Python. Обычно дескрипторы данных также имеют атрибуты [`__name__`](https://python-all.ru/3.4/reference/import.html#__name__) и `__doc__` (свойства, getsets и members имеют оба этих атрибута), но это не гарантировано.154155#### `inspect.isgetsetdescriptor(object)`156157Возвращает True, если объект является дескриптором getset.158159**Особенности реализации CPython:** getsets – это атрибуты, определённые в модулях расширения через структуры `PyGetSetDef`. Для реализаций Python без таких типов этот метод всегда возвращает `False`.160161#### `inspect.ismemberdescriptor(object)`162163Возвращает True, если объект является дескриптором члена.164165**Особенность реализации CPython:** Дескрипторы членов – это атрибуты, определяемые в модулях расширения через структуры [`PyMemberDef`](https://python-all.ru/3.4/c-api/structures.html#c.PyMemberDef). Для реализаций Python без таких типов этот метод всегда возвращает `False`.166167## 29.12.2. Получение исходного кода168169#### `inspect.getdoc(object)`170171Возвращает строку документации объекта, очищенную с помощью [`cleandoc()`](https://python-all.ru/3.4/library/inspect.html#inspect.cleandoc).172173#### `inspect.getcomments(object)`174175Возвращает единой строкой все строки комментариев, непосредственно предшествующие исходному коду объекта (для класса, функции или метода) или находящиеся в начале исходного файла Python (если объект – модуль).176177#### `inspect.getfile(object)`178179Возвращает имя (текстового или бинарного) файла, в котором определён объект. Это вызовет [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), если объект является встроенным модулем, классом или функцией.180181#### `inspect.getmodule(object)`182183Пытается определить модуль, в котором был определён объект.184185#### `inspect.getsourcefile(object)`186187Возвращает имя исходного файла Python, в котором определён объект. Это вызовет [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), если объект является встроенным модулем, классом или функцией.188189#### `inspect.getsourcelines(object)`190191Возвращает список строк исходного кода и номер начальной строки для объекта. Аргументом может быть модуль, класс, метод, функция, traceback, frame или code object. Исходный код возвращается в виде списка строк, соответствующих объекту, а номер строки указывает, где в исходном файле находится первая строка кода. Если исходный код не удаётся получить, возбуждается [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).192193Изменено в версии 3.3: [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError) возбуждается вместо [`IOError`](https://python-all.ru/3.4/library/exceptions.html#IOError), который теперь является его псевдонимом.194195#### `inspect.getsource(object)`196197Возвращает текст исходного кода объекта. Аргументом может быть модуль, класс, метод, функция, traceback, frame или code object. Исходный код возвращается в виде одной строки. Если исходный код не удаётся получить, возбуждается [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError).198199Изменено в версии 3.3: [`OSError`](https://python-all.ru/3.4/library/exceptions.html#OSError) возбуждается вместо [`IOError`](https://python-all.ru/3.4/library/exceptions.html#IOError), который теперь является его псевдонимом.200201#### `inspect.cleandoc(doc)`202203Убирает отступы из строк документации, которые добавлены для выравнивания с блоками кода. Удаляются все пробельные символы, которые можно равномерно убрать, начиная со второй строки. Также все табуляции заменяются пробелами.204205## 29.12.3. Интроспекция вызываемых объектов с помощью объекта Signature206207Новое в версии 3.3.208209Объект Signature представляет сигнатуру вызова вызываемого объекта и его аннотацию возврата. Чтобы получить объект Signature, используйте функцию [`signature()`](https://python-all.ru/3.4/library/inspect.html#inspect.signature).210211#### `inspect.signature(callable)`212213Возвращает объект [`Signature`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature) для заданного `callable`:214215```python216>>> from inspect import signature217>>> def foo(a, *, b:int, **kwargs):218... pass219220>>> sig = signature(foo)221222>>> str(sig)223'(a, *, b:int, **kwargs)'224225>>> str(sig.parameters['b'])226'b:int'227228>>> sig.parameters['b'].annotation229<class 'int'>230```231232Принимает широкий спектр вызываемых объектов Python: от обычных функций и классов до объектов [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial).233234Возбуждает [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError), если сигнатуру невозможно предоставить, и [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), если такой тип объекта не поддерживается.235236> **Примечание**237>238> Некоторые вызываемые объекты могут быть недоступны для интроспекции в определённых реализациях Python. Например, в CPython некоторые встроенные функции, определённые на C, не предоставляют метаданных о своих аргументах.239240#### `class inspect.Signature(parameters=None, *, return_annotation=Signature.empty)`241242Объект Signature представляет сигнатуру вызова функции и её аннотацию возврата. Для каждого параметра, принимаемого функцией, он хранит объект [`Parameter`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter) в своей коллекции [`parameters`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.parameters).243244Необязательный аргумент *parameters* представляет собой последовательность объектов [`Parameter`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter), которая проверяется: в ней не должно быть параметров с дублирующимися именами, параметры должны быть в правильном порядке (сначала только позиционные, затем позиционно-ключевые), а параметры со значениями по умолчанию должны следовать после параметров без них.245246Необязательный аргумент *return\_annotation* может быть произвольным объектом Python и является аннотацией возвращаемого значения вызываемого объекта.247248Объекты Signature являются *неизменяемыми*. Используйте [`Signature.replace()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.replace), чтобы создать изменённую копию.249250#### `empty`251252Специальный маркер уровня класса для указания отсутствия аннотации возврата.253254#### `parameters`255256Упорядоченное отображение имён параметров на соответствующие объекты [`Parameter`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter).257258#### `return_annotation`259260Аннотация возврата для вызываемого объекта. Если у вызываемого объекта нет аннотации возврата, этот атрибут устанавливается в [`Signature.empty`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.empty).261262#### `bind(*args, **kwargs)`263264Создаёт отображение позиционных и именованных аргументов на параметры. Возвращает [`BoundArguments`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments), если `*args` и `**kwargs` соответствуют сигнатуре, или вызывает исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError).265266#### `bind_partial(*args, **kwargs)`267268Работает так же, как [`Signature.bind()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind), но допускает пропуск некоторых обязательных аргументов (имитирует поведение [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial)). Возвращает [`BoundArguments`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments) или вызывает исключение [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError), если переданные аргументы не соответствуют сигнатуре.269270#### `replace(*[, parameters][, return_annotation])`271272Создаёт новый экземпляр Signature на основе экземпляра, для которого был вызван replace. Можно передать другие `parameters` и/или `return_annotation`, чтобы переопределить соответствующие свойства базовой сигнатуры. Чтобы удалить return\_annotation из скопированной Signature, передайте [`Signature.empty`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.empty).273274```python275>>> def test(a, b):276... pass277>>> sig = signature(test)278>>> new_sig = sig.replace(return_annotation="new return anno")279>>> str(new_sig)280"(a, b) -> 'new return anno'"281```282283#### `class inspect.Parameter(name, kind, *, default=Parameter.empty, annotation=Parameter.empty)`284285Объекты Parameter являются *неизменяемыми*. Вместо изменения объекта Parameter можно использовать [`Parameter.replace()`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter.replace) для создания изменённой копии.286287#### `empty`288289Специальный маркер уровня класса для указания отсутствия значений по умолчанию и аннотаций.290291#### `name`292293Имя параметра в виде строки. Имя должно быть допустимым идентификатором Python.294295#### `default`296297Значение по умолчанию для параметра. Если у параметра нет значения по умолчанию, этот атрибут устанавливается в [`Parameter.empty`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter.empty).298299#### `annotation`300301Аннотация для параметра. Если у параметра нет аннотации, этот атрибут устанавливается в [`Parameter.empty`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter.empty).302303#### `kind`304305Описывает, как значения аргументов привязываются к параметру. Возможные значения (доступны через [`Parameter`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter), например `Parameter.KEYWORD_ONLY`):306307| Имя | Значение |308| --- | --- |309| *POSITIONAL\_ONLY* | Значение должно передаваться как позиционный аргумент. В Python нет явного синтаксиса для определения только позиционных параметров, но многие встроенные функции и функции модулей расширения (особенно те, что принимают только один или два параметра) их поддерживают. |310| *POSITIONAL\_OR\_KEYWORD* | Значение может передаваться как ключевой, так и позиционный аргумент (это стандартное поведение привязки для функций, реализованных на Python). |311| *VAR\_POSITIONAL* | Кортеж позиционных аргументов, которые не привязаны ни к одному другому параметру. Это соответствует параметру `*args` в определении функции Python. |312| *KEYWORD\_ONLY* | Значение должно быть передано как именованный аргумент. Параметры, доступные только по ключу, – это те, которые следуют после записи `*` или `*args` в определении функции Python. |313| *VAR\_KEYWORD* | Словарь именованных аргументов, которые не привязаны ни к одному другому параметру. Это соответствует параметру `**kwargs` в определении функции Python. |314315Пример: вывод всех аргументов только для ключевой передачи без значений по умолчанию:316317```python318>>> def foo(a, b, *, c, d=10):319... pass320321>>> sig = signature(foo)322>>> for param in sig.parameters.values():323... if (param.kind == param.KEYWORD_ONLY and324... param.default is param.empty):325... print('Parameter:', param)326Parameter: c327```328329#### `replace(*[, name][, kind][, default][, annotation])`330331> Создаёт новый экземпляр Parameter на основе экземпляра, на котором был вызван метод replace. Чтобы переопределить атрибут [`Parameter`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter), передайте соответствующий аргумент. Чтобы удалить значение по умолчанию и/или аннотацию из параметра, передайте [`Parameter.empty`](https://python-all.ru/3.4/library/inspect.html#inspect.Parameter.empty).332>333> ```python334> >>> from inspect import Parameter335> >>> param = Parameter('foo', Parameter.KEYWORD_ONLY, default=42)336> >>> str(param)337> 'foo=42'338>339> >>> str(param.replace()) # Создаст поверхностную копию 'param'340> 'foo=42'341>342> >>> str(param.replace(default=Parameter.empty, annotation='spam'))343> "foo:'spam'"344> ```345346Изменено в версии 3.4: В Python 3.3 объектам Parameter разрешалось иметь `name` установленным в `None`, если их `kind` был установлен в `POSITIONAL_ONLY`. Это больше не разрешается.347348#### `class inspect.BoundArguments`349350Результат вызова [`Signature.bind()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind) или [`Signature.bind_partial()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind_partial). Содержит отображение аргументов на параметры функции.351352#### `arguments`353354Упорядоченное изменяемое отображение ([`collections.OrderedDict`](https://python-all.ru/3.4/library/collections.html#collections.OrderedDict)) имён параметров на значения аргументов. Содержит только явно связанные аргументы. Изменения в [`arguments`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.arguments) отразятся в [`args`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.args) и [`kwargs`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.kwargs).355356Следует использовать вместе с [`Signature.parameters`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.parameters) для любых целей обработки аргументов.357358> **Примечание**359>360> Аргументы, для которых [`Signature.bind()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind) или [`Signature.bind_partial()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind_partial) полагались на значение по умолчанию, пропускаются. Однако при необходимости их легко включить.361362```python363>>> def foo(a, b=10):364... pass365366>>> sig = signature(foo)367>>> ba = sig.bind(5)368369>>> ba.args, ba.kwargs370((5,), {})371372>>> for param in sig.parameters.values():373... if (param.name not in ba.arguments374... and param.default is not param.empty):375... ba.arguments[param.name] = param.default376377>>> ba.args, ba.kwargs378((5, 10), {})379```380381#### `args`382383Кортеж значений позиционных аргументов. Вычисляется динамически из атрибута [`arguments`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.arguments).384385#### `kwargs`386387Словарь значений именованных аргументов. Вычисляется динамически из атрибута [`arguments`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.arguments).388389#### `signature`390391Ссылка на родительский объект [`Signature`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature).392393Свойства [`args`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.args) и [`kwargs`](https://python-all.ru/3.4/library/inspect.html#inspect.BoundArguments.kwargs) можно использовать для вызова функций:394395```python396def test(a, *, b):397 ...398399sig = signature(test)400ba = sig.bind(10, b=20)401test(*ba.args, **ba.kwargs)402```403404> **См. также**405>406> **[**PEP 362**](https://python-all.ru/3.4/library/inspect.html) – объект сигнатуры функции.**407>408> Подробная спецификация, детали реализации и примеры.409410## 29.12.4. Классы и функции411412#### `inspect.getclasstree(classes, unique=False)`413414Упорядочивает заданный список классов в иерархию вложенных списков. Если встречается вложенный список, он содержит классы, унаследованные от класса, запись которого непосредственно предшествует этому списку. Каждая запись представляет собой кортеж из двух элементов, содержащий класс и кортеж его базовых классов. Если аргумент *unique* равен true, в возвращаемой структуре появляется ровно одна запись для каждого класса из заданного списка. В противном случае классы, использующие множественное наследование, и их потомки будут появляться несколько раз.415416#### `inspect.getargspec(func)`417418Получает имена и значения по умолчанию аргументов функции Python. Возвращается [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple) `ArgSpec(args, varargs, keywords, defaults)`. *args* – список имён аргументов. *varargs* и *keywords* – имена аргументов `*` и `**` или `None`. *defaults* – кортеж значений по умолчанию аргументов или `None`, если аргументов по умолчанию нет; если этот кортеж содержит *n* элементов, они соответствуют последним *n* элементам, перечисленным в *args*.419420Устарело с версии 3.0: Вместо этого используйте [`getfullargspec()`](https://python-all.ru/3.4/library/inspect.html#inspect.getfullargspec), который предоставляет информацию об именованных аргументах (keyword-only) и аннотациях.421422#### `inspect.getfullargspec(func)`423424Возвращает имена и значения по умолчанию аргументов функции Python. Возвращается [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple):425426`FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)`427428*args* – список имён аргументов. *varargs* и *varkw* – имена аргументов `*` и `**` или `None`. *defaults* – *n*-кортеж значений по умолчанию последних *n* аргументов, или `None`, если аргументов по умолчанию нет. *kwonlyargs* – список имён именованных аргументов (keyword-only). *kwonlydefaults* – словарь, отображающий имена из kwonlyargs в значения по умолчанию. *annotations* – словарь, отображающий имена аргументов в аннотации.429430Первые четыре элемента в кортеже соответствуют [`getargspec()`](https://python-all.ru/3.4/library/inspect.html#inspect.getargspec).431432> **Примечание**433>434> Рекомендуется использовать новый интерфейс [*объекта Signature*](https://python-all.ru/3.4/library/inspect.html#inspect-signature-object), который предоставляет лучший способ интроспекции функций.435436Изменено в версии 3.4: Эта функция теперь основана на [`signature()`](https://python-all.ru/3.4/library/inspect.html#inspect.signature), но по-прежнему игнорирует атрибуты `__wrapped__` и включает уже привязанный первый параметр в вывод сигнатуры для привязанных методов.437438#### `inspect.getargvalues(frame)`439440Получает информацию об аргументах, переданных в конкретный фрейм. Возвращается [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple) `ArgInfo(args, varargs, keywords, locals)`. *args* – список имён аргументов. *varargs* и *keywords* – имена аргументов `*` и `**` или `None`. *locals* – словарь локальных переменных данного фрейма.441442#### `inspect.formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]])`443444Форматирует красивое описание аргументов из значений, возвращаемых [`getargspec()`](https://python-all.ru/3.4/library/inspect.html#inspect.getargspec) или [`getfullargspec()`](https://python-all.ru/3.4/library/inspect.html#inspect.getfullargspec).445446Первые семь аргументов: (`args`, `varargs`, `varkw`, `defaults`, `kwonlyargs`, `kwonlydefaults`, `annotations`).447448Остальные шесть аргументов – это функции, которые вызываются для преобразования имён аргументов, имени аргумента `*`, имени аргумента `**`, значений по умолчанию, аннотации возвращаемого значения и отдельных аннотаций в строки соответственно.449450Например:451452```python453>>> from inspect import formatargspec, getfullargspec454>>> def f(a: int, b: float):455... pass456...457>>> formatargspec(*getfullargspec(f))458'(a: int, b: float)'459```460461#### `inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue])`462463Форматирует красивое описание аргументов из четырёх значений, возвращаемых [`getargvalues()`](https://python-all.ru/3.4/library/inspect.html#inspect.getargvalues). Аргументы format\* – это соответствующие необязательные функции форматирования, которые вызываются для преобразования имён и значений в строки.464465#### `inspect.getmro(cls)`466467Возвращает кортеж базовых классов класса cls, включая cls, в порядке разрешения методов (MRO). Ни один класс не встречается в этом кортеже более одного раза. Обратите внимание, что порядок разрешения методов зависит от типа cls. Если не используется особенная пользовательская метатипизация, cls будет первым элементом кортежа.468469#### `inspect.getcallargs(func, *args, **kwds)`470471Привязывает *args* и *kwds* к именам аргументов функции или метода Python *func*, как если бы она была вызвана с ними. Для привязанных методов также привязывает первый аргумент (обычно с именем `self`) к соответствующему экземпляру. Возвращается словарь, отображающий имена аргументов (включая имена аргументов `*` и `**`, если они есть) в их значения из *args* и *kwds*. В случае некорректного вызова *func*, т.е. когда `func(*args, **kwds)` вызвало бы исключение из-за несовместимой сигнатуры, возникает исключение того же типа и с тем же или похожим сообщением. Например:472473```python474>>> from inspect import getcallargs475>>> def f(a, b=1, *pos, **named):476... pass477>>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)}478True479>>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()}480True481>>> getcallargs(f)482Traceback (most recent call last):483...484TypeError: f() missing 1 required positional argument: 'a'485```486487Новое в версии 3.2.488489> **Примечание**490>491> Вместо этого рекомендуется использовать новый [`Signature.bind()`](https://python-all.ru/3.4/library/inspect.html#inspect.Signature.bind).492493#### `inspect.getclosurevars(func)`494495Получает отображение внешних ссылок на имена в функции или методе Python *func* на их текущие значения. Возвращается [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple) `ClosureVars(nonlocals, globals, builtins, unbound)`. *nonlocals* отображает ссылочные имена на лексические переменные замыкания, *globals* – на глобальные переменные модуля функции, а *builtins* – на встроенные функции, видимые из тела функции. *unbound* – это множество имён, на которые есть ссылки в функции, но которые не удалось разрешить при текущих глобальных переменных модуля и встроенных функциях.496497[`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) вызывается, если *func* не является функцией или методом Python.498499Новое в версии 3.3.500501#### `inspect.unwrap(func, *, stop=None)`502503Возвращает объект, обёрнутый в *func*. Следует цепочке атрибутов `__wrapped__`, возвращая последний объект в цепочке.504505*stop* – необязательный колбэк, принимающий один аргумент – объект в цепочке обёрток, и позволяющий досрочно завершить разворачивание, если колбэк возвращает истинное значение. Если колбэк никогда не возвращает истинное значение, возвращается последний объект в цепочке, как обычно. Например, [`signature()`](https://python-all.ru/3.4/library/inspect.html#inspect.signature) использует это, чтобы остановить разворачивание, если у какого-либо объекта в цепочке определён атрибут `__signature__`.506507[`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError) возбуждается, если обнаружен цикл.508509Новое в версии 3.4.510511## 29.12.5. Стек интерпретатора512513Когда следующие функции возвращают «записи фреймов» (frame records), каждая запись представляет собой кортеж из шести элементов: объект фрейма, имя файла, номер текущей строки, имя функции, список строк контекста из исходного кода и индекс текущей строки в этом списке.514515> **Примечание**516>517> Хранение ссылок на объекты фреймов (как в первом элементе записей фреймов, возвращаемых этими функциями) может привести к созданию циклических ссылок в программе. После создания циклической ссылки время жизни всех объектов, доступных из объектов, образующих цикл, может значительно увеличиться, даже если включён дополнительный детектор циклов Python. Если такие циклы необходимо создать, важно убедиться, что они явно разрываются, чтобы избежать задержки уничтожения объектов и увеличения потребления памяти.518>519> Хотя детектор циклов перехватит их, уничтожение фреймов (и локальных переменных) можно сделать детерминированным, удалив цикл в блоке [`finally`](https://python-all.ru/3.4/reference/compound_stmts.html#finally). Это также важно, если детектор циклов был отключён при компиляции Python или с помощью [`gc.disable()`](https://python-all.ru/3.4/library/gc.html#gc.disable). Например:520>521> ```python522> def handle_stackframe_without_leak():523> frame = inspect.currentframe()524> try:525> # Выполнить действие с фреймом526> finally:527> del frame528> ```529>530> Если нужно сохранить фрейм (например, чтобы вывести traceback позже), можно также разорвать циклические ссылки, используя метод [`frame.clear()`](https://python-all.ru/3.4/reference/datamodel.html#frame.clear).531532Необязательный аргумент *context*, поддерживаемый большинством этих функций, задаёт количество возвращаемых строк контекста, которые располагаются вокруг текущей строки.533534#### `inspect.getframeinfo(frame, context=1)`535536Возвращает информацию об объекте фрейма или traceback. Возвращается [*именованный кортеж*](https://python-all.ru/3.4/glossary.html#term-named-tuple) `Traceback(filename, lineno, function, code_context, index)`.537538#### `inspect.getouterframes(frame, context=1)`539540Возвращает список записей фреймов для фрейма и всех внешних фреймов. Эти фреймы представляют вызовы, которые привели к созданию *frame*. Первая запись в возвращаемом списке представляет *frame*; последняя запись представляет самый внешний вызов в стеке *frame*.541542#### `inspect.getinnerframes(traceback, context=1)`543544Возвращает список записей о фреймах для фрейма traceback и всех внутренних фреймов. Эти фреймы представляют вызовы, являющиеся следствием *frame*. Первый элемент списка представляет *traceback*; последний элемент представляет место, где было возбуждено исключение.545546#### `inspect.currentframe()`547548Возвращает объект фрейма для фрейма стека вызывающего.549550**Особенность реализации CPython:** Эта функция полагается на поддержку стековых фреймов Python в интерпретаторе, которая не гарантируется во всех реализациях Python. Если запуск происходит в реализации без поддержки стековых фреймов Python, эта функция возвращает `None`.551552#### `inspect.stack(context=1)`553554Возвращает список записей о фреймах для стека вызывающего кода. Первый элемент возвращаемого списка представляет вызывающий код; последний элемент представляет самый внешний вызов в стеке.555556#### `inspect.trace(context=1)`557558Возвращает список записей о фреймах для стека между текущим фреймом и фреймом, в котором было возбуждено исключение, обрабатываемое в данный момент. Первый элемент списка представляет вызывающий код; последний элемент представляет место, где было возбуждено исключение.559560## 29.12.6. Статическое получение атрибутов561562Как [`getattr()`](https://python-all.ru/3.4/library/functions.html#getattr), так и [`hasattr()`](https://python-all.ru/3.4/library/functions.html#hasattr) могут запускать выполнение кода при получении или проверке существования атрибутов. Дескрипторы, такие как свойства, будут вызваны, и [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__) и [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__) также могут быть вызваны.563564Для случаев, когда требуется пассивная интроспекция, например, в инструментах документации, это может быть неудобно. [`getattr_static()`](https://python-all.ru/3.4/library/inspect.html#inspect.getattr_static) имеет ту же сигнатуру, что и [`getattr()`](https://python-all.ru/3.4/library/functions.html#getattr), но не выполняет код при получении атрибутов.565566#### `inspect.getattr_static(obj, attr, default=None)`567568Извлекает атрибуты без запуска динамического поиска через протокол дескрипторов, [`__getattr__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattr__) или [`__getattribute__()`](https://python-all.ru/3.4/reference/datamodel.html#object.__getattribute__).569570Примечание: эта функция может быть не в состоянии получить все атрибуты, которые может получить getattr (например, динамически созданные атрибуты), и может найти атрибуты, которые getattr не может (например, дескрипторы, вызывающие AttributeError). Она также может возвращать объекты дескрипторов вместо членов экземпляра.571572Если [`__dict__`](https://python-all.ru/3.4/library/stdtypes.html#object.__dict__) экземпляра затенён другим членом (например, свойством), то эта функция не сможет найти члены экземпляра.573574Новое в версии 3.2.575576[`getattr_static()`](https://python-all.ru/3.4/library/inspect.html#inspect.getattr_static) не разрешает дескрипторы, например, дескрипторы слотов или getset-дескрипторы для объектов, реализованных на C. Возвращается объект дескриптора вместо базового атрибута.577578С ними можно работать с помощью кода вроде следующего. Обратите внимание, что для произвольных getset-дескрипторов их вызов может запустить выполнение кода:579580```python581# Пример кода для разрешения встроенных типов дескрипторов582class _foo:583 __slots__ = ['foo']584585slot_descriptor = type(_foo.foo)586getset_descriptor = type(type(open(__file__)).name)587wrapper_descriptor = type(str.__dict__['__add__'])588descriptor_types = (slot_descriptor, getset_descriptor, wrapper_descriptor)589590result = getattr_static(some_object, 'foo')591if type(result) in descriptor_types:592 try:593 result = result.__get__()594 except AttributeError:595 # Дескрипторы могут вызывать AttributeError, чтобы596 # указать, что нет нижележащего значения597 # в этом случае сам дескриптор будет598 # придется сделать599 pass600```601602## 29.12.7. Текущее состояние генератора603604При реализации планировщиков корутин и в других продвинутых применениях генераторов полезно определять, выполняется ли генератор в данный момент, ожидает ли он запуска или возобновления, или уже завершился. [`getgeneratorstate()`](https://python-all.ru/3.4/library/inspect.html#inspect.getgeneratorstate) позволяет легко определить текущее состояние генератора.605606#### `inspect.getgeneratorstate(generator)`607608Возвращает текущее состояние генератора-итератора.609610**Возможные состояния:**611612- GEN\_CREATED: Ожидание начала выполнения.613- GEN\_RUNNING: В настоящее время выполняется интерпретатором.614- GEN\_SUSPENDED: в данный момент приостановлена на выражении yield.615- GEN\_CLOSED: выполнение завершено.616617Новое в версии 3.2.618619Текущее внутреннее состояние генератора также можно запросить. Это полезно в основном для целей тестирования, чтобы убедиться, что внутреннее состояние обновляется должным образом:620621#### `inspect.getgeneratorlocals(generator)`622623Возвращает отображение живых локальных переменных в *generator* на их текущие значения. Возвращается словарь, отображающий имена переменных в значения. Это эквивалентно вызову [`locals()`](https://python-all.ru/3.4/library/functions.html#locals) в теле генератора, и все те же предостережения действуют.624625Если *generator* – это [*generator*](https://python-all.ru/3.4/glossary.html#term-generator) без текущего связанного фрейма, то возвращается пустой словарь. [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) возбуждается, если *generator* не является объектом-генератором Python.626627**Деталь реализации CPython:** Эта функция полагается на то, что генератор предоставляет стековый фрейм Python для интроспекции, что не гарантируется во всех реализациях Python. В таких случаях эта функция всегда будет возвращать пустой словарь.628629Новое в версии 3.3.630631## 29.12.8. Интерфейс командной строки632633Модуль [`inspect`](https://python-all.ru/3.4/library/inspect.html#module-inspect) также предоставляет базовую возможность интроспекции из командной строки.634635По умолчанию принимает имя модуля и выводит его исходный код. Класс или функцию внутри модуля можно вывести, добавив двоеточие и полное имя целевого объекта.636637#### `--details`638639Выводит информацию об указанном объекте, а не его исходный код.640