inspect.getmembers_static() lista atributos de um objeto sem executar a resolução dinâmica normal. Diferentemente de inspect.getmembers(), ele evita disparar descriptors, properties e alguns métodos __getattr__ ou __getattribute__. Isso o torna útil para ferramentas de documentação, análise de classes, debuggers e auditoria de APIs potencialmente perigosas.
O preço é que o resultado pode conter o descriptor bruto em vez do valor calculado e pode deixar de encontrar atributos criados apenas dinamicamente.
Primeiro exemplo
import inspect
class Exemplo:
@property
def valor(self):
print("property executada")
return 42
objeto = Exemplo()
print(inspect.getmembers_static(objeto))
A property aparece como objeto descriptor, sem executar o getter.
Diferença para getmembers
inspect.getmembers(objeto)
getmembers usa acesso normal e pode executar código. Uma property pode abrir arquivos, consultar rede, lançar exceções ou alterar estado. Em ferramentas genéricas, esse efeito pode ser indesejado.
Filtrando com predicate
membros = inspect.getmembers_static(
Exemplo,
predicate=inspect.isfunction,
)
O predicate recebe cada valor estático encontrado. Como descriptors não são vinculados, algumas funções podem aparecer em formatos diferentes do acesso normal.
Descriptors brutos
Ao inspecionar uma classe, você pode receber property, staticmethod, classmethod ou um descriptor personalizado. Isso é vantajoso quando a ferramenta precisa analisar a definição e não o resultado.
for nome, valor in inspect.getmembers_static(Exemplo):
if isinstance(valor, property):
print(nome, valor.fget)
Herança
A função considera atributos encontrados na hierarquia, seguindo regras estáticas de lookup. Se você precisa saber onde o atributo foi definido, percorra o __mro__ e examine o __dict__ de cada classe.
for classe in Exemplo.__mro__:
if "valor" in vars(classe):
print("definido em", classe)
Atributos dinâmicos podem faltar
class Dinamico:
def __getattr__(self, nome):
if nome.startswith("campo_"):
return nome.upper()
raise AttributeError(nome)
Como esses nomes não estão armazenados estaticamente, getmembers_static não os descobre. Isso é intencional.
Segurança não é isolamento completo
A função reduz execução acidental de descriptors, mas ainda examina objetos Python complexos. Não considere introspecção um sandbox. Evite importar módulos ou desserializar objetos não confiáveis apenas para analisá-los.
Documentação automática
Geradores de documentação podem usar a versão estática para coletar assinaturas, docstrings e descriptors sem inicializar recursos. Depois, podem escolher explicitamente quais membros são seguros para resolução normal.
Auditoria de properties
def listar_properties(classe):
return {
nome: valor
for nome, valor in inspect.getmembers_static(classe)
if isinstance(valor, property)
}
Esse padrão permite examinar getters e setters, ler docstrings e verificar convenções.
staticmethod e classmethod
O acesso normal vincula métodos. A introspecção estática pode devolver wrappers como staticmethod e classmethod. Use seus atributos internos ou __func__ quando precisar analisar a função original.
Objetos com metaclasses
Metaclasses podem criar atributos dinamicamente. A versão estática é útil para separar o que está realmente armazenado do que é sintetizado em runtime. Isso se relaciona ao guia interno sobre DynamicClassAttribute.
Comparando resultados
nomes_normais = {n for n, _ in inspect.getmembers(objeto)}
nomes_estaticos = {n for n, _ in inspect.getmembers_static(objeto)}
print(nomes_normais - nomes_estaticos)
A diferença pode revelar atributos dinâmicos. Execute a versão normal apenas quando os efeitos forem aceitáveis.
Erros comuns
- Esperar valores calculados de properties.
- Tratar um
staticmethodbruto como função vinculada. - Concluir que um atributo dinâmico não existe.
- Executar
getmembersem objetos desconhecidos antes da análise estática. - Usar introspecção como mecanismo de segurança.
Boas práticas
Comece pela análise estática, reconheça explicitamente tipos de descriptor, percorra o MRO quando precisar da origem e limite a resolução dinâmica a membros confiáveis. Consulte também os guias internos sobre inspect e inspect.signature.
Conclusão
inspect.getmembers_static permite observar a estrutura de objetos sem acionar muitos comportamentos dinâmicos. Ele é especialmente útil para documentação, auditoria e ferramentas que precisam examinar descriptors de forma controlada.







