Metaclasses em Python: o que são e como usar

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Metaclasses em Python — são classes especiais que criam e gerenciam outras classes. Como em Python tudo é um objeto, incluindo as classes, as metaclasses podem ser vistas como "classes para classes". Elas fornecem um mecanismo para controlar o processo de criação de classes e modificar seu comportamento no momento da definição.

Como funcionam as metaclasses

Quando o Python encontra uma definição de classe, ele automaticamente usa a metaclasse type para criar essa classe. O processo funciona assim:

class MinhaClasse:
    pass

Internamente, o Python executa:

MinhaClasse = type('MinhaClasse', (), {})

Onde:

  • 'MinhaClasse' — nome da classe
  • () — tupla de classes pai
  • {} — dicionário de atributos e métodos da classe

A metaclasse embutida type é responsável por criar todas as classes em Python por padrão.

Criando suas próprias metaclasses

Metaclasses personalizadas são criadas herdando de type e sobrescrevendo seus métodos:

class MinhaMeta(type):
    def __new__(cls, name, bases, attrs):
        print(f"Criando classe {name}")
        attrs['criada_por_metaclasse'] = True
        return super().__new__(cls, name, bases, attrs)

class MinhaClasse(metaclass=MinhaMeta):
    pass

print(MinhaClasse.criada_por_metaclasse)  # True

Métodos principais das metaclasses

__new__

Controla a criação da classe. É chamado antes de __init__ e retorna a nova classe:

class MetaCriacao(type):
    def __new__(cls, name, bases, attrs):
        # Modificação de atributos antes da criação da classe
        attrs['id_classe'] = id(cls)
        return super().__new__(cls, name, bases, attrs)

__init__

Inicializa a classe já criada:

class MetaInit(type):
    def __init__(cls, name, bases, attrs):
        print(f"Inicializando classe {name}")
        super().__init__(name, bases, attrs)

__call__

Define o comportamento ao criar instâncias da classe:

class MetaCall(type):
    def __call__(cls, *args, **kwargs):
        print(f"Criando instância de {cls.__name__}")
        return super().__call__(*args, **kwargs)

Exemplos práticos de uso

Conversão automática de atributos

class MetaUpperAttr(type):
    def __new__(cls, name, bases, attrs):
        uppercase_attrs = {}
        for attr_name, attr_value in attrs.items():
            if not attr_name.startswith('__'):
                uppercase_attrs[attr_name.upper()] = attr_value
            else:
                uppercase_attrs[attr_name] = attr_value
        return super().__new__(cls, name, bases, uppercase_attrs)

class MinhaClasse(metaclass=MetaUpperAttr):
    attr1 = 'valor1'
    attr2 = 'valor2'

print(hasattr(MinhaClasse, 'ATTR1'))  # True
print(hasattr(MinhaClasse, 'attr1'))  # False

Implementação do padrão Singleton

class MetaSingleton(type):
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class ConexaoBanco(metaclass=MetaSingleton):
    def __init__(self):
        print("Criando conexão com o banco de dados")

db1 = ConexaoBanco()
db2 = ConexaoBanco()
print(db1 is db2)  # True

Validação da estrutura de classes

class MetaValidacao(type):
    def __new__(cls, na                

Blogs

Book Recommendations