Skip to content

Instantly share code, notes, and snippets.

@rik0
Last active December 27, 2015 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rik0/7367887 to your computer and use it in GitHub Desktop.
Save rik0/7367887 to your computer and use it in GitHub Desktop.
Metaclass madness.
import functools as ft
class IAmAPig(type):
@classmethod
def _make_aux(cls, base, k, attribute):
super_meth = getattr(base, k, None)
if super_meth is not None:
@ft.wraps(attribute)
def aux(self, *args, **kwargs):
super_meth(self, *args, **kwargs)
return attribute(self, *args, **kwargs)
return aux
else:
return None
@classmethod
def _customize(cls, base, dct):
updated = {}
for k, attribute in dct.iteritems():
if callable(attribute):
updated_attribute = cls._make_aux(base, k, attribute)
if updated_attribute is not None:
updated[k] = updated_attribute
dct.update(updated)
@classmethod
def _find_base(cls, name, bases, dct):
for base in bases:
if isinstance(base, IAmAPig):
return base
else:
return None
def __new__(cls, name, bases, dct):
base = cls._find_base(name, bases, dct)
if base is not None:
cls._customize(base, dct)
return super(IAmAPig, cls).__new__(cls, name, bases, dct)
class Base(object):
__metaclass__ = IAmAPig
def foo(self):
print 'Base'
class Child(Base):
def foo(self):
print 'Child'
def bar(self):
print 'Bar'
c = Child()
c.foo()
c.bar()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment