inspect.getmembers_static() lista atributos sin usar la resolución dinámica normal. A diferencia de inspect.getmembers(), evita ejecutar muchos descriptors, properties y rutas personalizadas de __getattr__ o __getattribute__. Esto lo hace útil para documentación, debugging, análisis de clases y auditoría de APIs.
La contrapartida es que el resultado puede contener descriptors brutos en vez de valores calculados y puede omitir atributos creados únicamente en runtime.
Ejemplo básico
import inspect
class Ejemplo:
@property
def valor(self):
print("property ejecutada")
return 42
objeto = Ejemplo()
print(inspect.getmembers_static(objeto))
La property aparece como descriptor sin ejecutar su getter.
Diferencia frente a getmembers
inspect.getmembers(objeto) realiza acceso normal y puede ejecutar código. Una property podría abrir archivos, acceder a red, lanzar excepciones o cambiar estado.
Filtrar con predicate
miembros = inspect.getmembers_static(
Ejemplo,
predicate=inspect.isfunction,
)
El predicate recibe cada valor estático. Como los descriptors no se vinculan, algunos valores difieren del acceso normal.
Descriptors brutos
La inspección estática puede devolver property, staticmethod, classmethod y descriptors personalizados. Es útil cuando se necesita analizar la definición y no el resultado.
for nombre, valor in inspect.getmembers_static(Ejemplo):
if isinstance(valor, property):
print(nombre, valor.fget)
Herencia y origen
Para descubrir dónde se definió un atributo, recorre el MRO y examina el diccionario de cada clase.
for clase in Ejemplo.__mro__:
if "valor" in vars(clase):
print("definido en", clase)
Atributos dinámicos ausentes
class Dinamico:
def __getattr__(self, nombre):
if nombre.startswith("campo_"):
return nombre.upper()
raise AttributeError(nombre)
Esos nombres se sintetizan y no están guardados, por lo que la inspección estática no los descubre.
No es un sandbox
La función reduce ejecución accidental de descriptors, pero introspección no significa aislamiento. No importes módulos no confiables ni deserialices objetos inseguros solo para analizarlos.
Documentación automática
Una herramienta puede recopilar descriptors, docstrings y definiciones estáticamente y resolver después únicamente miembros considerados seguros.
Auditar properties
def listar_properties(clase):
return {
nombre: valor
for nombre, valor in inspect.getmembers_static(clase)
if isinstance(valor, property)
}
staticmethod y classmethod
El acceso normal vincula métodos. La inspección estática puede devolver el wrapper. Usa __func__ cuando necesites analizar la función original.
Metaclases
Las metaclases pueden sintetizar atributos. La versión estática separa definiciones almacenadas de comportamiento runtime. Se relaciona con la guía interna sobre DynamicClassAttribute.
Comparar resultados
normales = {n for n, _ in inspect.getmembers(objeto)}
estaticos = {n for n, _ in inspect.getmembers_static(objeto)}
print(normales - estaticos)
La diferencia puede revelar miembros dinámicos. Ejecuta el lookup normal solo cuando sus efectos sean aceptables.
Errores comunes
- Esperar valores calculados de properties.
- Tratar un
staticmethodbruto como función vinculada. - Concluir que un atributo dinámico no existe.
- Usar primero la inspección normal sobre objetos desconocidos.
- Considerar la introspección una frontera de seguridad.
Buenas prácticas
Empieza por la inspección estática, reconoce tipos de descriptor, recorre el MRO cuando importe el origen y resuelve valores dinámicos solo en miembros confiables. Consulta las guías internas sobre inspect e inspect.signature.
Conclusión
inspect.getmembers_static muestra la estructura de un objeto evitando buena parte de la ejecución dinámica. Es especialmente útil para documentación, auditoría y análisis de descriptors.







