Skip to content

Instantly share code, notes, and snippets.

Last active August 29, 2015 14:24
What would you like to do?
A curiosity for your programming zoo inspired by monty python,
famous philosophers, and GVR's multimethods demo.
This code demonstrates metaprogramming as well as runtime reflection
and introspection. It also shows python's flexibility by bending language
semantics and demonstrates that python's "self" is convention (not keyword).
import inspect
import new
import sys
registry = {}
class proxy(object):
""" master registry for methodnames,
decorators, and the proxy scope
dummy object
def personalityDependant(func):
""" have to save func in the registry so each duplicate
function name doesnt just overwrite the previous one
NOTE: "which_self" is the name of the variable used where
"self" is usually found in instancemethod definitions
which_self = inspect.getargspec(func)[0][0]
if which_self not in registry:
registry[which_self] = {}
registry[which_self][func.__name__] = func
return func
def schizophrenic(func):
""" tag a function as schizophrenic so the
metaclass knows when to effect the scope
func.schizophrenic = True
return func
class schizotypal(type):
""" metaclass for all schizoids """
def __new__(mcls, name, bases, clsdict):
err1 = ('expected a schizotypal object would '
'have a list of personalities.')
if 'personalities' not in clsdict:
raise TypeError(err1)
personalities = clsdict['personalities']
replacement = {}
for pName in personalities:
replacement[pName] = registry[pName]
personalities = replacement
clsdict['personalities'] = personalities
klassobj = type.__new__(mcls, name, bases, clsdict)
return klassobj
def __call__(cls, *args, **kargs):
inst = type.__call__(cls, *args, **kargs)
for var in dir(inst):
val = getattr(inst, var)
test = var != '__metaclass__' and var != '__class__'
if hasattr(val, 'schizophrenic'):
for pName in inst.personalities:
val.func_globals[pName] = inst._as(pName)
return inst
class schizoid(object):
""" base schizoid object (inherit from this) """
__metaclass__ = schizotypal
personalities = []
def _as(self, pName):
""" this method is used to obtain a representation
of self with respect to a specific personality
cls = self.__class__
err = 'illegal personality for ' + str(cls) + ': ' + pName
assert pName in cls.personalities, err
out = cls.personalities[pName]
P = proxy()
for funcname in out:
func = out[funcname]
func = new.instancemethod(func, self, cls)
setattr(P, funcname, func)
return P
class myschizoid(schizoid):
""" a simple demo.
NB: without the decorators, each status() definition below would simply
overwrite the previous one. notice also under normal python semantics
how theres no reason the philosopher names in the run() method should
be in scope.
personalities = ['kant', 'heidegger', 'wittgenstein', 'schlegel']
def status(kant):
return "a real pissant"
def status(heidegger):
return "a boozy beggar"
def status(wittgenstein):
return "beery swine"
def status(schlegel):
return "schloshed"
def run(self):
print 'kant:\t\t\t', kant.status()
print 'heidegger:\t\t', heidegger.status()
print 'wittgenstein:\t\t', wittgenstein.status()
print 'schlegel:\t\t', schlegel.status()
if __name__ == '__main__':
s = myschizoid()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment