Introspecção ou reflexão é capacidade do software de identificar e relatar suas próprias estruturas internas, tais como tipos, escopo de variáveis, métodos e atributos.
Funções nativas do interpretador para introspecção:
Função | Retorno |
---|---|
type(objeto) |
O tipo (classe) do objeto |
id(objeto) |
O identificador do objeto |
locals() |
O dicionário de variáveis locais |
globals() |
O dicionário de variáveis globais |
vars(objeto) |
O dicionário de símbolos do objeto |
len(objeto) |
O tamanho do objeto |
dir(objeto) |
A lista de estruturas do objeto |
help(objeto) |
As Doc Strings do objeto |
repr(objeto) |
A representação do objeto |
isinstance(objeto, classe) |
Verdadeiro se objeto deriva da classe |
issubclass(subclasse, classe) |
Verdadeiro se subclasse herda classe |
O identificador do objeto é um número inteiro único que é usado pelo interpretador para identificar internamente os objetos.
Exemplo:
# Colhendo algumas informações
# dos objetos globais no programa
from types import ModuleType
def info(n_obj):
# Cria uma referência ao objeto
obj = globals()[n_obj]
# Mostra informações sobre o objeto
print 'Nome do objeto:', n_obj
print 'Identificador:', id(obj)
print 'Tipo:', type(obj)
print 'Representação:', repr(obj)
# Se for um módulo
if isinstance(obj, ModuleType):
print 'itens:'
for item in dir(obj):
print item
print
# Mostrando as informações
for n_obj in dir()[:10]: # O trecho [:10] é apenas para limitar os objetos
info(n_obj)
Nome do objeto: ALLOW_THREADS Identificador: 31976616 Tipo: <type 'int'> Representação: 1 Nome do objeto: Annotation Identificador: 52522064 Tipo: <type 'type'> Representação: <class 'matplotlib.text.Annotation'> Nome do objeto: Arrow Identificador: 49643312 Tipo: <type 'type'> Representação: <class 'matplotlib.patches.Arrow'> Nome do objeto: Artist Identificador: 48410704 Tipo: <type 'type'> Representação: <class 'matplotlib.artist.Artist'> Nome do objeto: AutoLocator Identificador: 49376208 Tipo: <type 'type'> Representação: <class 'matplotlib.ticker.AutoLocator'> Nome do objeto: Axes Identificador: 55538128 Tipo: <type 'type'> Representação: <class 'matplotlib.axes.Axes'> Nome do objeto: BUFSIZE Identificador: 37513920 Tipo: <type 'int'> Representação: 8192 Nome do objeto: Button Identificador: 51026320 Tipo: <type 'type'> Representação: <class 'matplotlib.widgets.Button'> Nome do objeto: CLIP Identificador: 31976640 Tipo: <type 'int'> Representação: 0 Nome do objeto: Circle Identificador: 49578336 Tipo: <type 'type'> Representação: <class 'matplotlib.patches.Circle'>
O Python também tem um módulo chamado types, que tem as definições dos tipos básicos do interpretador.
Exemplo:
import types
s = ''
if isinstance(s, types.StringType):
print 's é uma string.'
s é uma string.
Através da introspecção, é possível determinar os campos de uma tabela de banco de dados, por exemplo.
O módulo inspect provê um conjunto de funções de alto nível para introspecção que permitem investigar tipos , itens de coleções, classes, funções, código fonte e a pilha de execução do interpretador.
Exemplo:
import os.path
# inspect: módulo de introspecção "amigável"
import inspect
print 'Objeto:', inspect.getmodule(os.path)
print 'Classe?', inspect.isclass(str)
# Lista todas as funções que existem em "os.path"
print 'Membros:',
for name, struct in inspect.getmembers(os.path):
if inspect.isfunction(struct):
print name,
Objeto: <module 'posixpath' from '/usr/lib/python2.7/posixpath.pyc'> Classe? True Membros: _joinrealpath abspath basename commonprefix dirname exists expanduser expandvars getatime getctime getmtime getsize isabs isdir isfile islink ismount join lexists normcase normpath realpath relpath samefile sameopenfile samestat split splitdrive splitext walk
As funções que trabalham com a pilha do interpretador devem ser usadas com cuidado, pois é possível criar referências cíclicas (uma variável que aponta para o item da pilha que tem a própria variável). A existência de referências a itens da pilha retarda a destruição dos itens pelo coletor de lixo do interpretador.