2.33. Introspecção¶
Um conjunto de built-ins permite que um programa em execução se inspecione a si próprio – os valores com que está a trabalhar, os namespaces onde esses valores residem e as relações entre classes. Recorra a eles quando precisar de tomar decisões com base naquilo que um objeto realmente é, em vez de naquilo que o seu chamador afirma que é.
2.33.1. Identidade e hash¶
id()– um inteiro único que identifica um objeto enquanto ele existir. Dois nomes que referenciam o mesmo objeto devolvem o mesmo id; dois objetos iguais mas distintos não.
>>> a = [1, 2, 3]
>>> b = a
>>> c = [1, 2, 3]
>>> id(a) == id(b) # same list
True
>>> id(a) == id(c) # equal but distinct
False
O id não é portável entre execuções e não tem significado além de «mesmo objeto ou objeto diferente.»
hash()– o valor de hash de um objeto, o mesmo número quedictesetutilizam para o localizar. Dois objetos iguais produzem o mesmo hash; apenas os tipos hashable (valores imutáveis, na maioria) funcionam.
>>> hash("abc") # some integer, build-dependent
-1600925533
>>> hash([1, 2])
TypeError: unhashable type: 'list'
2.33.2. Consultar tipos e capacidade de chamada¶
type()– a classe exata de um valor.type(x) is intpergunta «x é exatamente um int» (sem subclasses);isinstance()é habitualmente o que se pretende.isinstance()– «x é uma instância desta classe, ou de uma sua subclasse?» A ferramenta padrão para despacho baseado em tipos dentro de funções.issubclass()– o equivalente ao nível de classes. Recebe duas classes em vez de uma instância.callable()–Truese o argumento puder ser chamado com(). Útil quando se recebe um argumento que pode ser uma função ou um valor simples.
>>> isinstance(3, int)
True
>>> isinstance(True, int) # bool is a subclass of int
True
>>> issubclass(bool, int)
True
>>> callable(len)
True
>>> callable(10)
False
Um padrão que usa callable:
def call_or_return(x):
return x() if callable(x) else x
2.33.3. Examinar âmbitos¶
globals()– o namespace global do módulo como umdict. Ler a partir dele funciona; escrever nele é real, mas fazê-lo fora da exploração no REPL torna um programa difícil de acompanhar.locals()– o namespace local no ponto de chamada. Dentro de uma função reflete as variáveis locais; modificar o dict devolvido não garante a escrita de volta nas locais reais (comportamento definido pela implementação).
name = "OpenMV"
def f():
x = 10
print(globals()["name"]) # OpenMV
print(locals()) # {'x': 10}
Estes dois são úteis para depuração e para ferramentas que precisam de descobrir o que está definido. Recorra a eles com parcimónia no código regular – uma função que muta globals() é uma das coisas mais difíceis de raciocinar em Python.
2.33.4. Ver também¶
dir() e help(), abordados em debugging, são as ferramentas de introspecção do quotidiano para explorar a interface de um objeto desconhecido.