DynamicClassAttribute: descriptors e acesso dinâmico

Publicado em: 30/08/2026
Tempo de leitura: 3 minutos
Close-up of a python snake curled up, showcasing its detailed scales.

types.DynamicClassAttribute é um descriptor especializado que se comporta como uma propriedade quando acessado por uma instância, mas permite que o acesso pela classe seja encaminhado ao __getattr__ da própria classe. Esse comportamento é incomum e foi criado para APIs em que um mesmo nome precisa ter significado diferente no nível da instância e no nível da classe.

O exemplo mais conhecido está relacionado a Enum. Antes de usar o recurso diretamente, é importante entender descriptors, propriedades e metaclasses.

Comportamento básico

from types import DynamicClassAttribute

class Item:
    def __init__(self, valor):
        self._valor = valor

    @DynamicClassAttribute
    def valor(self):
        return self._valor

item = Item(10)
print(item.valor)

Na instância, o descriptor funciona de forma semelhante a property.

Acesso pela classe

Quando Item.valor é acessado, o descriptor levanta AttributeError. Isso permite que uma metaclass com __getattr__ forneça uma resposta dinâmica.

class Meta(type):
    def __getattr__(cls, nome):
        if nome == "valor":
            return "valor calculado na classe"
        raise AttributeError(nome)

class Item(metaclass=Meta):
    @DynamicClassAttribute
    def valor(self):
        return 42

print(Item().valor)
print(Item.valor)

A instância retorna 42; a classe usa o fallback da metaclass.

Diferença para property

Uma property comum acessada pela classe normalmente devolve o próprio objeto descriptor. DynamicClassAttribute foi projetado para provocar o caminho de atributo ausente no nível da classe.

Descriptors e __get__

Descriptors controlam acesso por meio de métodos como __get__, __set__ e __delete__. DynamicClassAttribute encapsula esse protocolo e suporta getter, setter e deleter, assim como property.

class Registro:
    def __init__(self):
        self._codigo = "A1"

    @DynamicClassAttribute
    def codigo(self):
        return self._codigo

    @codigo.setter
    def codigo(self, valor):
        self._codigo = str(valor)

Uso com metaclasses

O recurso só mostra seu diferencial quando a classe usa uma metaclass capaz de responder dinamicamente. O método __getattr__ deve ser implementado na metaclass, não como método de instância da classe.

Por que Enum usa uma ideia semelhante

Enums precisam distinguir membros, atributos de instância e resolução de nomes no nível da classe. O mecanismo permite que nomes sejam tratados dinamicamente sem perder propriedades úteis nas instâncias.

Quando usar

  • Frameworks com metaclasses e namespaces dinâmicos.
  • APIs em que o mesmo nome tem semântica distinta na classe e na instância.
  • Implementações inspiradas em Enum.
  • Ferramentas de introspecção ou proxies de tipos.

Quando evitar

Na maioria das aplicações, nomes diferentes ou métodos de classe explícitos são mais claros. O recurso aumenta a complexidade de introspecção, autocompletar, documentação e análise estática. Não o use apenas para economizar um nome.

Introspecção

getattr(Classe, nome) pode executar o fallback dinâmico. Para inspecionar descriptors sem dispará-los, use inspect.getattr_static ou inspect.getmembers_static.

import inspect

descriptor = inspect.getattr_static(Item, "valor")
print(type(descriptor))

Tipagem

Type checkers podem não compreender completamente namespaces produzidos por metaclasses. Considere stubs, overloads ou protocolos e mantenha a API pública simples.

Erros comuns

  • Implementar __getattr__ na classe em vez da metaclass.
  • Esperar que o acesso pela classe devolva o descriptor.
  • Criar recursão dentro de __getattr__.
  • Usar o mecanismo onde uma property normal bastaria.
  • Ignorar ferramentas de introspecção e documentação.

Boas práticas

Restrinja o recurso a infraestrutura, teste acesso por classe e instância, preserve mensagens de AttributeError e documente claramente a semântica dupla. Leia também os guias internos sobre módulo types, Enums e introspecção.

Conclusão

DynamicClassAttribute combina comportamento de propriedade na instância com resolução dinâmica no nível da classe. É poderoso em frameworks baseados em metaclasses, mas deve ser usado com parcimônia devido à complexidade adicionada.

Fontes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    A laptop screen showing a code editor with visible programming code in a dimly lit environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    UserList no Python: listas customizadas

    Aprenda UserList no Python para criar listas customizadas com validação, normalização, regras de mutação e APIs previsíveis.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    Close-up of a person underlining text in a dictionary on a desk with a laptop.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    UserDict no Python: dicionários customizados

    Aprenda UserDict no Python para criar dicionários customizados com validação, normalização, composição e APIs previsíveis.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.accumulate: somas e estados cumulativos

    Aprenda itertools.accumulate no Python para somas, saldos, máximos progressivos e estados cumulativos em pipelines eficientes.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.groupby: agrupe dados ordenados corretamente

    Aprenda itertools.groupby no Python para agrupar dados ordenados, agregar streams e evitar erros com subiteradores compartilhados.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: riscos ao trocar diretórios

    Aprenda contextlib.chdir no Python, seus riscos com estado global e concorrência e quando preferir pathlib ou subprocess cwd.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    nullcontext no Python: contextos opcionais

    Use nullcontext no Python para unificar contextos opcionais, recursos já abertos, locks e transações sem duplicar código.

    Ler mais

    Tempo de leitura: 5 minutos
    30/08/2026