Create a gist now

Instantly share code, notes, and snippets.

Proof of concept for tying a metaclass auto-decorator with a service bus
from collections import defaultdict
from functools import wraps
decoratedCalls = defaultdict(list)
def call(name, *args, **kwargs):
print name, args, kwargs
if name in decoratedCalls:
for cb in decoratedCalls[name]:
cb(*args, **kwargs)
class Subscribe(object):
def __init__(self, name):
self.name = name
def __call__(self, f):
decoratedCalls[self.name].append(f)
return f
class BusDecorator(object):
def __init__(self, name):
self.name = name
def __call__(self, f):
@wraps(f)
def decorator(inst, *args, **kwargs):
call("%s-pre" % self.name, inst, args, kwargs)
retval = f(inst, *args, **kwargs)
call("%s-post" % self.name, inst, retval)
return retval
return decorator
class BusWrap(type):
def __new__(mcs, clsname, bases, cdict):
dbg = 1
modName = cdict.get("__module__", "unknownclass")
for name in cdict.keys():
prefix = "%s.%s.%s" % ( modName, clsname, name)
if callable(cdict[name]):
cdict[name] = BusDecorator(prefix)(cdict[name])
return type.__new__(mcs, name, bases, cdict)
class Foo(object):
__metaclass__ = BusWrap
def __init__(self):
print "init'd"
def bar(self):
print "bar"
def blah(self):
print "blah"
def ich(self):
print "ich"
def ego(self):
print "lego"
def say(self, *args):
print "Saying ", args
@Subscribe("__main__.Foo.bar-pre")
def preBar(inst, *args, **kwargs):
if not hasattr(inst, "ext_info"):
inst.ext_info = "Here"
@Subscribe("__main__.Foo.ego-post")
def postEgo(inst, *args, **kwargs):
if hasattr(inst, "ext_info"):
print "Extended info is ", inst.ext_info
x = Foo()
x.bar()
x.blah()
x.ich()
x.ego()
x.say("abba", "dabba")
dbg = 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment