00001 ############################################################################### 00002 00003 import inspect, new, sys 00004 00005 registry = {} 00006 00007 # master registry for methodnames, decorators, and proxy scope dummy object 00008 ############################################################################### 00009 00010 class proxy(object): pass 00011 00012 ## 00013 # we have to save func in the registry so each duplicate 00014 # function name doesnt just overwrite the previous one 00015 # 00016 # NOTE: "whichSelf" is the name of the variable used where 00017 # "self" is usually found in instancemethod definitions 00018 # 00019 def personalityDependant(func): 00020 whichSelf = inspect.getargspec(func)[0][0] 00021 if whichSelf not in registry: registry[whichSelf] = {} 00022 registry[whichSelf][func.__name__] = func 00023 return func 00024 00025 ## 00026 # tag a function as schizophrenic so the metaclass knows when to 00027 # effect the scope mangling. 00028 def schizophrenic(func): 00029 func.schizophrenic=True 00030 return func 00031 00032 # metaclass for all schizoids 00033 ############################################################################### 00034 00035 ## 00036 # 00037 class schizotypal(type): 00038 @staticmethod 00039 def __new__(mcls, name, bases, clsdict): 00040 err1 ='expected a schizotypal object would have a list of personalities.' 00041 try: assert 'personalities' in clsdict 00042 except AssertionError: raise Exception, err1 00043 else: 00044 personalities = clsdict['personalities'] 00045 replacement = {} 00046 for pName in personalities: replacement[pName] = registry[pName] 00047 personalities = replacement 00048 clsdict['personalities'] = personalities 00049 klassobj = type.__new__(mcls, name, bases, clsdict) 00050 return klassobj 00051 00052 def __call__(cls, *args, **kargs): 00053 inst = type.__call__(cls, *args, **kargs) 00054 for var in dir(inst): 00055 val = getattr(inst, var) 00056 test = var!='__metaclass__' and var!='__class__' 00057 if hasattr(val, 'schizophrenic') and test: 00058 for pName in inst.personalities: 00059 val.func_globals[pName] = inst.as_(pName) 00060 return inst 00061 00062 # base schizoid object (inherit from this) 00063 ############################################################################### 00064 00065 ## 00066 # 00067 class schizoid(object): 00068 __metaclass__ = schizotypal 00069 personalities = [] 00070 00071 ## 00072 # obtain a representation of self with respect to some personality 00073 def as_(self, pName): 00074 cls = self.__class__ 00075 err = 'illegal personality for '+str(cls) + ': ' + pName 00076 assert pName in cls.personalities, err 00077 out = cls.personalities[pName] 00078 P = proxy() 00079 for funcname in out: 00080 func = out[funcname] 00081 func = new.instancemethod(func,self,cls) 00082 setattr(P, funcname, func) 00083 return P 00084 00085 # a demo 00086 ############################################################################### 00087 00088 if __name__=='__main__': 00089 ## 00090 # a simple demo. 00091 # 00092 # note that without the decorators, each status() definition would simply 00093 # overwrite the previous one. notice also under normal python semantics 00094 # how theres no reason the philosopher names in the run() method should 00095 # be in scope. 00096 # 00097 class myschizoid(schizoid): 00098 personalities = ['kant','heidegger','wittgenstein','schlegel'] 00099 00100 @personalityDependant 00101 def status(kant): return "a real pissant" 00102 00103 @personalityDependant 00104 def status(heidegger): return "a boozy beggar" 00105 00106 @personalityDependant 00107 def status(wittgenstein): return "beery swine" 00108 00109 @personalityDependant 00110 def status(schlegel): return "schloshed" 00111 00112 @schizophrenic 00113 def run(self): 00114 print 00115 print 'kant:\t\t\t', kant.status() 00116 print 'heidegger:\t\t', heidegger.status() 00117 print 'wittgenstein:\t\t', wittgenstein.status() 00118 print 'schlegel:\t\t', schlegel.status() 00119 print 00120 00121 s = myschizoid() 00122 s.run() 00123 00124 00125 00126 00127
© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved; If you reference this document or any part of this document you must use the citation verbatim (including the link) "© Copyright 2008-2009 Vyper Logix Corp., All Right Reserved."
Notice: This source code contained in this document is NOT open source and is NOT being distributed as open source.
122,241 lines of code and growing...