Интроспекция в Python

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Python поддерживает полную интроспекцию (отражение) времени исполнения, в том числе интроспекцию типа (type introspection (англ.)). Это означает, что для любого объекта можно получить всю информацию о его внутренней структуре и среде исполнения. Возможности интроспекции можно условно разделить на две группы: стандартные (описанные в документации по языку (англ.)) и нестандартные (характерные для конкретной реализации языка, например, CPython).

Примеры[править | править код]

Необходимые для интроспекции данные хранятся в специальных атрибутах. Так, например, получить все пользовательские атрибуты большинства объектов можно из специального атрибута — словаря (или другого объекта, предоставляющего интерфейс dict) __dict__

 >>> class x(object):pass
 ....
 >>> f = x()
 >>> f.attr = 12
 >>> print f.__dict__
 {'attr': 12}
 >>> print x.__dict__       # т.к. классы тоже являются экземплярами объекта type
                            # то и они поддерживают этот тип интроспекции
 {'__dict__': <attribute '__dict__' of 'x' objects>, '__module__'.......

Есть также другие атрибуты, имена и назначение которых зависят от объекта:

 >>> def f():pass
 ....
 >>> f.func_code.co_code    # получение байтокода функции
 'd\x00\x00S'
 >>> f.__class__            # специальный атрибут - ссылка на класс данного объекта
 <type 'function'>

Подавляющее большинство атрибутов, поддерживающих интроспекцию, являются классовыми, и их, в свою очередь, можно получить из obj.__class__.__dict__. Часть информации, унаследованную от базового класса, все объекты используют совместно, что позволяет экономить память.

Модуль inspect[править | править код]

Для удобства получения интроспективной информации в Python есть модуль inspect[1].

 >>> def f(x,y = 10,**mp):pass
 ...
 >>> inspect.getargspec(f)
 (['x', 'y'], None, 'mp', (10,))

Модуль new[править | править код]

С помощью модуля new возможен обратный процесс — построения объекта из составных частей на этапе исполнения

 >>> def f(i): return j + i
 ....
 >>> j = 2
 >>> f(1)
 3
 >>> import new
 >>> g = new.function(f.func_code, {'j': 23})
 >>> g(1)
 24

Примечания[править | править код]

  1. Beazley, 2009, pp. 222-225.

Литература[править | править код]