Python para Desenvolvedores

2ª edição, revisada e ampliada

Capítulo 14: Introspecção


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)
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:

In [2]:
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.

Inspect

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, 
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.

In [1]:
 
Out[1]: