- Модуль inspect в Python
- Предоставление образца модуля
- Изучение модуля
- Получение классов
- Изучение методов класса
- Проверка объектов класса
- Получение строки документации для класса
- Получение исходного кода класса
- Получение источника метода
- Получение подписи метода
- inspect — Инспекция «живых» объектов на Python
- Типы и члены
- inspect.getmembers(object[, predicate])
- inspect.getmoduleinfo(path)
- inspect.getmodulename(path)
- inspect.ismodule(object)
- inspect.isclass(object)
- inspect.ismethod(object)
- inspect.isfunction(object)
Модуль inspect в Python
Модуль inspect Python – очень полезный модуль, который используется для интроспекции объектов в программе и просмотра исходного кода модулей, классов и функций, которые используются во всей программе.
Модуль фактически может использоваться для извлечения исходного кода самой функции, анализа аргументов, которые эта функция принимает.
Предоставление образца модуля
Сейчас мы создадим образец модуля с некоторыми функциями, классами и строками документации в Python. Вот фрагмент кода для sample.py:
def module_funct(arg1, arg2 = 'default', *args): """This is a module-level function.""" local_var = arg1 * 3 return local_var class X(object): """Definition for X class.""" def __init__(self, name): self.name = name def get_name(self): "Returns the name of the instance." return self.name x_obj = X('sample_instance') class Y(X): """This is the Y class, child of X class. """ # This method is not part of X class. def do_something(self): """Anything can be done here.""" def get_name(self): "Overrides version from X" return 'Y(' + self.name + ')'
Теперь, когда у нас есть образец модуля, готовый к использованию, мы можем начать извлекать и анализировать его исходный код, строку документации и детали объекта. Давайте начнем.
Изучение модуля
Давайте начнем с самоанализа определенного нами образца модуля. Обратите внимание, что для этого у нас есть файл образца модуля sample.py в том же каталоге, в котором мы выполняем наши скрипты. Вот фрагмент образца кода о том, как мы можем проверить наш модуль:
import inspect import sample for name, data in inspect.getmembers(sample): if name.startswith('__'): continue print('<> : '.format(name, data))
Посмотрим на результат этой программы:
Получение классов
Мы можем получить все классы, присутствующие в модуле, и предпринять действия, когда найдем класс, который искали:
import inspect import sample for key, data in inspect.getmembers(sample, inspect.isclass): print('<> : '.format(key, data))
Посмотрим на результат этой программы:
Изучение методов класса
На этот раз мы пойдем дальше, исследуя методы, присутствующие в классе. Обратите внимание, что мы используем один и тот же метод getmembers, отличается только идентификатор свойства, то есть isfunction:
import inspect from pprint import pprint import sample pprint(inspect.getmembers(sample.X, inspect.isfunction))
Посмотрим на результат этой программы:
Проверка объектов класса
С помощью модуля inspect можно отслеживать все экземпляры класса, созданные в программе, с помощью одного вызова функции:
import inspect from pprint import pprint import sample x = sample.X(name='inspect_getmembers') pprint(inspect.getmembers(x, inspect.ismethod))
Посмотрим на результат этой программы:
Получение строки документации для класса
Модуль inspect часто используется в инструментах Python, которые автоматизируют процесс извлечения классов и строк документации их методов, которые могут быть представлены конечным пользователям. Это означает, что разработчик может просто поместить строки документации в метод, и ту же строку можно использовать для представления другому разработчику приложения:
import inspect import sample print('X.__doc__:') print(sample.X.__doc__) print() print('getdoc(X):') print(inspect.getdoc(sample.X))
Получение исходного кода класса
В интеллектуальных средах, таких как IDE, модуль inspect используется для представления исходного кода модулей, классов и функций:
import inspect import sample print(inspect.getsource(sample.Y))
Посмотрим на результат этой программы:
Получение источника метода
На этот раз мы получаем исходный код только одного метода:
import inspect import sample print(inspect.getsource(sample.Y.get_name))
Посмотрим на результат этой программы:
Получение подписи метода
В качестве последнего примера мы получим сигнатуру метода, который часто используется в Intellisense IDE, чтобы представить разработчикам, какие аргументы принимает метод:
import inspect import sample print(inspect.signature(sample.module_funct))
Посмотрим на результат этой программы:
inspect — Инспекция «живых» объектов на Python
Модуль inspect на Python предоставляет множество полезных функций, которые помогают Вам получить информацию о живых объектах, таких как модули, классы, методы, функции, трассировка, объекты фрейма и кода. Например, он может помочь Вам проверить контекст класса, получить исходный код метода, извлечь и отформатировать список аргументов для функции, или получить всю информацию, которая Вам нужна для отображения подробной трассировки.
Есть четыре основных вида сервисов, предоставляемых этим модулем: проверка типа, получение исходного кода, инспекция классов и функций, и проверка стэка интерпретатора.
Типы и члены
Функция getmembers() получает члены объекта, такого как класс или модуль. Шестнадцать функций, чьи имена начинаются с is в основном являются подходящим выбором в качестве второго аргумента для getmembers(). Кроме того, они помогают Вам определить, когда Вы можете ожидать обнаружить следующие специальные атрибуты:
Тип | Атрибут | Описание |
---|---|---|
module | __doc__ | строка документации |
__file__ | имя файла (отсутствует для встроенных модулей) | |
class | __doc__ | строка документации |
__module__ | имя модуля в котором определён этот класс | |
method | __doc__ | строка документации |
__name__ | имя, с которым был определён этот метод | |
im_class | объект класса, у которого запрашивается этот метод | |
im_func или __func__ | объект функции, содержащий реализацию метода | |
im_self or __self__ | экземпляр, к которому привязан метод, или None | |
function | __doc__ | строка документации |
__name__ | имя, с которым эта функция была определена | |
func_code | объект кода, содержащий скомпилированный bytecode функции | |
func_defaults | кортеж значений по умолчанию для аргументов | |
func_doc | (то же, что и __doc__) | |
func_globals | глобальное пространство имён, в котором была определена функция | |
func_name | (то же, что и __name__) | |
generator | __iter__ | определена для поддержки итерации через контейнер |
close | вызывает исключение GeneratorExit внутри генератора, чтобы прекратить итерацию | |
gi_code | объект кода | |
gi_frame | объект фрейма или, возможно, None, если генератор был исчерпан | |
gi_running | равен 1, если генератор исчерпан, иначе 0 | |
next | возвращает следующий элемент из контейнера | |
send | возобновляет генератор и посылает значение, которое становится результатом текущего выражения yield | |
throw | используется для возбуждения исключения внутри генератора | |
traceback | tb_frame | объект фрейма на этом уровне |
tb_lasti | индекс последней применённой инструкции в байткоде | |
tb_lineno | номер текущей строки в исходном коде Python | |
tb_next | следующий внутренний объект трассировки (вызываемый на этом уровне) | |
frame | f_back | следующий внешний объект фрейма (вызывающий этот фрейм) |
f_builtins | встроенное пространство имён, видимое этим фреймом. | |
f_code | объект кода, выполняемый в этом фрейме | |
f_exc_traceback | трассировка, если есть в этом фрейме, иначе None | |
f_exc_type f_exc_type | тип исключения, если возникает в этом фрейме, иначе None | |
f_exc_value | значение исключения, если возникает в этом фрейме, иначе None | |
f_globals f_globals | глобальное пространство имён, видимое этим фреймом | |
f_lasti f_lasti | индекс последней выполненной инструкции в байткоде | |
f_lineno | номер текущей строки в исходном коде Python | |
f_locals f_locals | локальное пространство имён, видимое в этом фрейме | |
f_restricted | 0 или 1, если фрейм находится в ограниченном режиме выполнения | |
f_trace | трассировочная функции для этого фрейма, или None | |
code | co_argcount | число аргументов (не включая аргументы * или **) |
co_code | строка, или сырой скомпилированный байт-код | |
co_consts co_consts | кортеж констант, используемых в байт-коде | |
co_filename | имя файла, в котором этот объект кода был создан | |
co_firstlineno | номер первой строки в исходном коде Python | |
co_flags | bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg | |
co_lnotab | кодированное отображение номер стр+оки на индекс байт-кода | |
co_name | имя, с которым этот объект кода был определён | |
co_names | кортеж имён локальных переменных | |
co_nlocals co_nlocals | количество локальных переменных | |
co_stacksize | требуемый стек для виртуальной машины | |
co_varnames | кортеж имён аргументов и локальных переменных | |
builtin | __doc__ | строка документации |
__name__ | оригинальные имя этой функции или метода | |
__self__ | экземпляр, к которому привязан этот метод, или None |
inspect.getmembers(object[, predicate])
Возвращает все члены объекта в списке, состоящем из пар вида (name, value), отсортированных по имени. Если передан не обязательный аргумент predicate, то будут включены только те члены, для которых predicate возвращает True.
getmembers() не возвращает атрибуты метакласса, если аргумент является классом (это поведение унаследовано из функции dir()).
inspect.getmoduleinfo(path)
Возвращает кортеж значений, который описывает как Python будет интерпретировать файл, определяемый path, если это модуль, или None, если он не может быть идентифицирован как модуль. Возвращаемый кортеж имеет вид (name, suffix, mode, module_type)«, где *name — имя модуля без имён окружающих его пакетов, suffix — оставшаяся часть имени файла (может не быть расширением с точкой), mode — режим для функции open(), который будет использоваться (‘r’ или ‘rb’) и module_type — число, определяющее тип модуля. module_type будет иметь значение, которое можно сравнить с константами, определёнными в модуле imp, более подробную информацию можно найти в документации к тому модулю.
Changed in version 2.6: Возвращает named tuple ModuleInfo(name, suffix, mode, module_type).
inspect.getmodulename(path)
Возвращает имя модуля, определённого путём path, без окружающих его пакетов. Используется тот же самый алгоритм, который использует интерпретатор при поиске модулей. Если по этому имени по правилам интерпретатора невозможно найти модуль будет возвращено None.
inspect.ismodule(object)
Возвращает true, если объект является модулем.
inspect.isclass(object)
Возвращает true, если объект является классом, не важно, встроенным или пользовательским.
inspect.ismethod(object)
Возвращает true, если объект является связанным методом, написанным на Python.
inspect.isfunction(object)
Возвращает true, если объект является функцией Python, сюда же относятся функции, созданные при помощи выражения lambda.
Примечание: встроенные функции возвращают false: