2.33. Introspección¶
Un puñado de funciones incorporadas permiten que un programa en ejecución se inspeccione a sí mismo – los valores con los que trabaja, los espacios de nombres en los que viven esos valores y las relaciones entre clases. Recurre a ellas cuando necesites tomar decisiones basadas en lo que un objeto realmente es, en lugar de lo que quien lo llama afirma que es.
2.33.1. Identidad y hashing¶
id()– un entero único que identifica un objeto mientras esté vivo. Dos nombres que vinculan el mismo objeto devuelven el mismo id; dos objetos iguales pero distintos no.
>>> 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
El id no es portable entre ejecuciones y no tiene más significado que «mismo objeto u objeto distinto».
hash()– el valor hash de un objeto, el mismo número quedictysetusan para buscarlo. Dos objetos iguales producen el mismo hash; solo funcionan los tipos hashables (valores inmutables, en su mayoría).
>>> hash("abc") # some integer, build-dependent
-1600925533
>>> hash([1, 2])
TypeError: unhashable type: 'list'
2.33.2. Consultar tipos y la capacidad de ser llamado¶
type()– la clase exacta de un valor.type(x) is intpregunta «¿es x exactamente un int?» (sin subclases);isinstance()suele ser lo que quieres en su lugar.isinstance()– «¿es x una instancia de esta clase, o de una subclase suya?» La herramienta estándar para el despacho basado en tipos dentro de funciones.issubclass()– la contraparte a nivel de clases. Toma dos clases en lugar de una instancia.callable()–Truesi el argumento puede llamarse con(). Útil cuando recibes un argumento que puede ser una función o puede ser un valor simple.
>>> isinstance(3, int)
True
>>> isinstance(True, int) # bool is a subclass of int
True
>>> issubclass(bool, int)
True
>>> callable(len)
True
>>> callable(10)
False
Un patrón que usa callable:
def call_or_return(x):
return x() if callable(x) else x
2.33.3. Examinar los ámbitos¶
globals()– el espacio de nombres global del módulo como undict. Leer de él funciona; escribir en él es real, pero hacerlo fuera de la exploración en el REPL hace que un programa sea difícil de seguir.locals()– el espacio de nombres local en el punto de la llamada. Dentro de una función refleja las variables locales; modificar el diccionario devuelto no garantiza que se escriba de vuelta en las locales reales (comportamiento definido por la implementación).
name = "OpenMV"
def f():
x = 10
print(globals()["name"]) # OpenMV
print(locals()) # {'x': 10}
Estas dos son útiles para depurar y para herramientas que necesitan descubrir qué está definido. Recurre a ellas con moderación en código normal – una función que muta globals() es una de las cosas más difíciles de razonar en Python.
2.33.4. Véase también¶
dir() y help(), tratadas en depuración, son las herramientas de introspección de uso diario para explorar la superficie de un objeto desconocido.