On 13 Mar, 17:42, Jack Diederich <jackd...@gmail.com> wrote: > On Sat, Mar 13, 2010 at 12:10 PM, Jon Clements <jon...@googlemail.com> wrote: > > On 13 Mar, 16:42, Jack Diederich <jackd...@gmail.com> wrote: > >> On Sat, Mar 13, 2010 at 11:19 AM, Jon Clements <jon...@googlemail.com> > >> wrote: > >> > This is semi-experimental and I'd appreciate opinions of whether it's > >> > the correct design approach or not. It seems like a good idea, but it > >> > doesn't mean it is. > > >> > I have a class 'A', this provides standard support functions and > >> > exception handling. > >> > I have 'B' and 'C' which specialise upon 'A' > > >> > What I'd like to achieve is something similar to: > > >> > @inject(B): > >> > def some_function(a, b): > >> > pass # something useful > > >> > The name 'some_function' is completely redundant -- don't need it, > >> > don't actually care about the function afterwards, as long as it > >> > becomes a __call__ of a 'B' *instance*. > > >> > I've basically got a huge list of functions, which need to be the > >> > callable method of an object, and possibly at run-time, so I don't > >> > want to do: > > >> > class Something(B): > >> > def __call__(self, etc.. etc...): > >> > pass # do something > > >> > I've got as far as type(somename, (B,), {}) -- do I then __init__ or > >> > __new__ the object or... > > >> > In short, the function should be the __call__ method of an object that > >> > is already __init__'d with the function arguments -- so that when the > >> > object is called, I get the result of the the function (based on the > >> > objects values). > > >> I'm not sure exactly what you are asking for, but if what you want is > >> a bunch of different objects that vary only by their class's __call__ > >> you could do it with a function that returns a new class based on A > >> but with a new __call__: > > >> def make_new_call_class(base_class, call_func): > >> class NewClass(base_class): > >> def __call__(self, *args, **kw): > >> return call_func(self, *args, *kw) > >> return NewClass > > >> or the return could even be NewClass() [return an instance] if this is > >> a one off. > > >> That said, I'm not really sure what this behavior is good for. > > >> -Jack > > > Cheers Jack for the response. > > > The behaviour is to not derive from a class, but rather allow > > the decorators to do so... so I would like to iterate over > > a list of functions (don't care what they're called) and then > > inject the function as a method. If needs be at run-time. > > > Say I have 1000 functions (okay, admittedly over quoted), but > > I don't want every programmer to inherit from 'B' or 'C', but > > to 'inject'. So the idea is that classes are pre-defined, have > > predictable behaviour, *except* the __call__ is different. > > > You are correct in this. Why do I want that behaviour? -> > > > - It's easier, no inheriting from a class, when needs not. > > - Some integrity (anyone can define a function and 'inject' to the > > Management class) > > - Easier maintainability - maybe :) > > > for i in function_list: > > i = inject(function_list) > > > At the end of the day: > > def blah(x, y, z): > > pass > > > That should be the callable of the object. > > I'm still not sure why you are trying to do this, but you can do it > with delegation. Have the parent class's __call__ look for an > instance attribute named call_this and then call it, ex/ > > class A(): > def __call__(self, *args, **kw): > self.call_this(*args, **kw) # we grab this off the instance > > ob = A() > def my_func(*stuff): pass > ob.call_this = my_func > > -Jack
Jack, thanks very much for your replies -- hugely appreciated. I was delayed by the missus calling me for dinner - I'd forgotten we had a stew going in the slow cooker, and she can't make dumplings to save her life :) If I can re-explain slightly, say I have a class 'compute': class Compute(object): def __init__(self, something): self.something = something # misc other methods here..... then... class ComputeAdd(Compute): pass If I do, @inject def ComputeAdd(fst, snd): return fst + snd The end result should be a new class called ComputeAdd __init__'d with fst and snd, which when called, returns fst + snd. Hope that makes sense. Cheers, Jon. -- http://mail.python.org/mailman/listinfo/python-list