Skip to content

Instantly share code, notes, and snippets.

@filipeximenes
Last active January 22, 2016 20:28
Show Gist options
  • Save filipeximenes/e79e27809da6bc30fc9d to your computer and use it in GitHub Desktop.
Save filipeximenes/e79e27809da6bc30fc9d to your computer and use it in GitHub Desktop.
Python Metaclasses
# executando algo antes da criação
class MeuTipo(type):
def __new__(cls, name, parents, dct):
print 'aqui!'
return super(MeuTipo, cls).__new__(cls, name, parents, dct)
class MinhaClasse(object):
__metaclass__ = MeuTipo
# trocando o nome da class
class TrocaNome(type):
def __new__(cls, name, parents, dct):
return super(TrocaNome, cls).__new__(cls, 'Bike', parents, dct)
class Carro(object):
__metaclass__ = TrocaNome
# modificando atributos
class Fantasma(type):
def __new__(cls, name, parents, dct):
return super(Fantasma, cls).__new__(cls, name, parents, {'bu': 'aaaaaaaaaaaaahhhhhh'})
class Wat(object):
__metaclass__ = Fantasma
foo = 1
Wat().foo
Wat().bu
# retornando outra class
class Magica(type):
def __new__(cls, name, parents, dct):
return Wat
class Zueira(object):
__metaclass__ = Magica
# coding: utf-8
class Megazord(type):
def __new__(cls, name, parents, dct):
print 'Hora de morfar'
return super(Megazord, cls).__new__(cls, name, parents, dct)
# init é chamado depois que a classe já foi criada
def __init__(cls, name, parents, dct):
if not hasattr(cls, 'registry'):
# apenas a primeira classe criada com este tipo
cls.registro = {}
else:
# todas as outras classes
interface_id = name.lower()
cls.registro[interface_id] = cls
print cls, cls.registro
super(Megazord, cls).__init__(name, parents, dct)
class PowerRanger(object):
__metaclass__ = Megazord
class PowerRangerVermelho(PowerRanger):
pass
class PowerRangerVerde(PowerRanger):
pass
type # é uma classe do tipo 'type'
type(int) # o construtor de type retorna o tipo de uma classe
type(1) # ou o tipo de uma instancia
MinhaClasse = type('MinhaClasse', (), {}) # o construtor de type também pode criar novas classes
print MinhaClasse # classe
print MinhaClasse() # instancia
# um pouco mais interesante
NovaClasse = type('Novaclasse', (), {'um': 1, 'dois': 2})
print NovaClasse.um
print NovaClasse.dois
MaisUma = type('MaisUma', (), {'mais_dois': lambda self, x: x + 2})
m = MaisUma()
print m.mais_dois(3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment