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:
In [5]:
# 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)
O Python também tem um módulo chamado types, que tem as definições dos tipos básicos do interpretador.
Exemplo:
In [2]:
import types
s = ''
if isinstance(s, types.StringType):
print '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:
In [3]:
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,
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.
In [1]:
Out[1]: