On Aug 21, 10:14 am, Bruno Desthuilliers <bruno. [EMAIL PROTECTED]> wrote: > Gabriel Rossetti a écrit : > > > > > Bruno Desthuilliers wrote: > >> Gabriel Rossetti a écrit : > >>> Terry Reedy wrote: > >> (snip) > >>>> Unlike the class approach, this requires recreating the constant > >>>> functions and dict with each call to _test. Quick to write but a > >>>> bit 'dirty', in my opinion. Another standard idiom is to set up the > >>>> constants outside the function: > > >>>> def request(params): > >>>> pass > >>>> def submit(params, values): > >>>> pass > >>>> def update(params, values): > >>>> pass > >>>> def delete(params): > >>>> pass > >>>> dispatch = {'request':request, 'submit':submit, 'update':update, > >>>> 'delete':delete} > > >>>> def _test(self, action, *args): > >>>> return resultToXmo(dispatch[action](*args)) > > >>> That's how I had done it originally (before the use of eval()), but > >>> in this case also, since the functions are still nested, > > >> Uh ??? You probably want to re-read the above code snippet. > > > Uh...yes, I didn't see the external/parent function was no longer there. > > I prefer to nest mine though because I have several parent functions for > > different tasks, so each child/nested function has a diff. > > implementation, I find that cleaner than having n*4+n top-level > > functions (+ n dicts), e.g. I prefer this : > > > def __task1(self, action, *args): > > def request(params): > > pass > > def submit(params, values): > > pass > > def update(params, values): > > pass > > def delete(params): > > pass > > return resultToXml(locals()[action](*args)) > > > def __task2(self, action, *args): > > def request(params): > > pass > > def submit(params, values): > > pass > > def update(params, values): > > pass > > def delete(params): > > pass > > return resultToXml(locals()[action](*args)) > > > over this : > > (snip) > > > I could use your callable approach, but like you said it may not be > > worth the trouble. > > The "trouble" I was talking about was not with using callable objects, > but with trying to hack func.func_code to extract nested functions (if > ever possible). > > But anyway... The point of using callable objects is to avoid going thru > the whole "setup" part again and again and again. Now if all your task > functions only differ by the dispatch dict, there's at least another > ways to avoid this runtime repetition - as well as coding repetition > FWIW (warning : untested code): > > def _make_task(func): > dispatch = func() > def _task(action, *args): > return resultToXml(dispatch[action](*args)) > _task.__name__ = _task.func_name = func.__name__ > return _task > > @_make_task > def _task1(): > def request(params): > pass > def submit(params, values): > pass > def update(params, values): > pass > def delete(params): > pass > return locals() > > HTH
Here's more ideas: Use a wrapper to give the function access to itself as an object: @auto def f( self, arg ): assert self== f In your original example: @auto def toto( toto ): def titi(): pass f = getattr(toto, "titi") print str(f) Should work, untested. Another is to use a wrapper to participate functions in a dictionary: @entry( 'a' ) def a( arg ): a_stuff( ) @entry( 'b' ) def b( arg ): b_stuff You could even make 'entry' a class instance, so you can specialize and vary it in other cases, untested. Last one is just use a class, untested: class __Test: def __test(self, action, *args): result = getattr(self, action)(*args) return resultToXml(result) def request(self,params): pass def submit(self,params, values): pass def update(self,params, values): pass def delete(self,params): pass Keep us posted which one works for you. -- http://mail.python.org/mailman/listinfo/python-list