On 10 Dec 2004 15:03:01 -0800, [EMAIL PROTECTED] wrote: >>Well, that could be a feature, depending on what your use case is. >>Or you could make a method for adding methods, I suppose. >>A perfectly transparent wrap of obj would be to do nothing ;-) >>What do you actually want to do? > >Actually, the very best would if only type(), isinstance() and the >is-keyword could an object and a wrapped version of it apart. > >I've thought of using a weakdict instaed, problem is, it would be a >little bit too transparent for my purpose as the only way to tell an >object and a wrapped version of it apart would be by my own functions >which would do lookups in that dict. Secondly, it would only allow for >one comment per object dopy, which would fail horribly for e.g. numbers >(there are hundreds of uses of the number 1, which all needs different >comments for the number). >
Here is a different approach, which I think will perform better than masses of descriptors and delegations and individual classes, plus wrapping is just a single assignment. See the W0, W1, W2 usage in the example below. The idea is to clone the object's class as a subclass in a factory (wrapperclass) function that takes an example object plus a second argument containing new or overriding methods and/or class variables. This add-ins argument is just a class, and everything except what comes in an empty class (i.e., ['__dict__', '__module__', '__weakref__', '__doc__'] ) is copied from the dict in to the wrapper class dict, which is initialized as a clone of the object's class dict. ----< wrapo.py >----------------------------------------- # wrapo.py -- wrapperclass factory and usage examples # 20041211 01:02:54 -- bokr # Use at your own risk. Alpha. def wrapperclass(obj, AddIns): """ Create a (sub)class which may be assigned to obj.__class__ to change the obj instance's apparent available methods and class variables, taking additions from a supplied AddIns class serving as a container for methods and variables. """ cdict = dict(type(obj).__dict__) for name, value in AddIns.__dict__.items(): if name not in ['__dict__', '__module__', '__weakref__', '__doc__']: cdict[name] = value cname = 'Wrapped_%s_%s'%(AddIns.__name__, type(obj).__name__) W = type(cname, (type(obj),), cdict) return W import time class Wrap_one(object): cvar = 'Wrap_one cvar' def now(self): return 'W1: '+time.ctime() def __repr__(self): return 'Wrap_one %r repr:\n %s'%(self.kw, object.__repr__(self)) def __add__(self, other): return '%r + %r'%(self,str(other)) class Wrap_two(object): # let orig cvar alone def now(self): return 'W2: '+time.ctime() def __repr__(self): return 'Wrap_two %r repr:\n %s'%(self.args, object.__repr__(self)) def __add__(self, other): return '%r + %r'%(type(self).__name__, str(other)) def test(): class Foo(object): cvar = 'orig Foo cvar ;-)' def __init__(self, *args, **kw): self.args = args self.kw =kw def now(self): return '(time n/a)' def __str__(self): return '%s %r\n %s'%(self.now(), self.cvar, repr(self)) foo = Foo(1,2,3, x=111,y=222) W0 = type(foo) W1 = wrapperclass(foo, Wrap_one) W2 = wrapperclass(foo, Wrap_two) print '--- plain foo:\n', foo for w in (W0, W1, W2, W0): foo.__class__ = w print '\n---- %s ----' % type(foo).__name__ print foo if w!=W0: print foo + ' a %s string.'%w.__name__ bar = Foo(22,33,bar='this is bar') for w in (W0, W1, W2, W0): bar.__class__ = w print '\n---- %s ----' % type(bar).__name__ print bar if __name__ == '__main__': test() --------------------------------------------------------- Result: [ 1:16] C:\pywk\clp\wrapper>wrapo.py --- plain foo: (time n/a) 'orig Foo cvar ;-)' <__main__.Foo object at 0x00901630> ---- Foo ---- (time n/a) 'orig Foo cvar ;-)' <__main__.Foo object at 0x00901630> ---- Wrapped_Wrap_one_Foo ---- W1: Sat Dec 11 01:16:40 2004 'Wrap_one cvar' Wrap_one {'y': 222, 'x': 111} repr: <__main__.Wrapped_Wrap_one_Foo object at 0x00901630> Wrap_one {'y': 222, 'x': 111} repr: <__main__.Wrapped_Wrap_one_Foo object at 0x00901630> + ' a Wrapped_Wrap_one_Foo string.' ---- Wrapped_Wrap_two_Foo ---- W2: Sat Dec 11 01:16:40 2004 'orig Foo cvar ;-)' Wrap_two (1, 2, 3) repr: <__main__.Wrapped_Wrap_two_Foo object at 0x00901630> 'Wrapped_Wrap_two_Foo' + ' a Wrapped_Wrap_two_Foo string.' ---- Foo ---- (time n/a) 'orig Foo cvar ;-)' <__main__.Foo object at 0x00901630> ---- Foo ---- (time n/a) 'orig Foo cvar ;-)' <__main__.Foo object at 0x00901390> ---- Wrapped_Wrap_one_Foo ---- W1: Sat Dec 11 01:16:40 2004 'Wrap_one cvar' Wrap_one {'bar': 'this is bar'} repr: <__main__.Wrapped_Wrap_one_Foo object at 0x00901390> ---- Wrapped_Wrap_two_Foo ---- W2: Sat Dec 11 01:16:40 2004 'orig Foo cvar ;-)' Wrap_two (22, 33) repr: <__main__.Wrapped_Wrap_two_Foo object at 0x00901390> ---- Foo ---- (time n/a) 'orig Foo cvar ;-)' <__main__.Foo object at 0x00901390> Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list