Metaclasses?
Michael Hudson
mwh21 at cam.ac.uk
Wed Apr 26 09:45:16 EDT 2000
Donald Beaudry <donb at init.com> writes:
> quinn at hedono.ugcs.caltech.edu (Quinn Dunkan) wrote,
> > Anyway, even if you could figure out the ambiguity problem, I don't
> > think metaclasses would help you, bytecodehacks might.
>
> *If* bytecodehacks could help, metaclasses could be used to make
> calling them neat and clean. The idea is that during class
> instantiation the metaclass would, using bytecodehacks, rewrite all of
> the class's methods. This might confuse the poor guy who comes along
> and tries to derive a new class from one of these 'self less'.
What, like this? :-)
This has recieved light testing only, so be suitably careful.
deadline-on-Tuesday?-no-I-must-have-imagined-it-ly y'rs
Michael
from bytecodehacks.code_editor import Function
from bytecodehacks.ops import *
import types
def rewrite_method(meth,attrs):
f = Function(meth)
code = f.func_code
cs = code.co_code
code.co_varnames.insert(0,"self")
code.co_names.insert(0,"self")
i = 0
while i < len(cs):
op = cs[i]
if op.__class__ in [LOAD_FAST,STORE_FAST,DELETE_FAST]:
op.arg = op.arg + 1
if (op.has_name_or_local() and op.name in attrs
and op.__class__ not in [LOAD_ATTR,STORE_ATTR]):
if op.arg < code.co_argcount:
raise ValueError, "parameter also instance member!"
if op.__class__ in [LOAD_FAST, LOAD_NAME, LOAD_GLOBAL]:
attrop = LOAD_ATTR
else:
attrop = STORE_ATTR
cs[i:i+1] = [LOAD_FAST(0),attrop(op.name)]
i = i + 2
else:
i = i + 1
code.co_argcount = code.co_argcount + 1
return f.make_function()
class SelflessClass:
def __init__(self,name,bases,ns):
self.__name__ = name
self.__bases__ = bases
self.__namespace__ = ns
if ns.has_key('__attrs__'):
attrs = ns['__attrs__']
for k,v in ns.items():
if type(v) is types.FunctionType:
ns[k] = rewrite_method(v,attrs)
def __call__(self):
return SelflessInstance(self)
class MetaMethodWrapper:
def __init__(self, func, inst):
self.func = func
self.inst = inst
self.__name__ = self.func.__name__
def __call__(self, *args, **kw):
return apply(self.func, (self.inst,) + args, kw)
class SelflessInstance:
def __init__(self,klass):
self.__klass__ = klass
try:
init = self.__klass__.__namespace__["__init__"]
except:
pass
else:
init(self)
def __getattr__(self, name):
try:
value = self.__klass__.__namespace__[name]
if type(value) is types.FunctionType:
return MetaMethodWrapper(value,self)
else:
return value
except KeyError:
raise AttributeError, name
Selfless = SelflessClass("Selfless",(),{})
class MyClass(Selfless):
__attrs__ = ["a"]
def __init__():
a = 1
def get_a():
return a
def set_a(newa):
a = newa
--
If i don't understand lisp, it would be wise to not bray about
how lisp is stupid or otherwise criticize, because my stupidity
would be archived and open for all in the know to see.
-- Xah, comp.lang.lisp
More information about the Python-list
mailing list