A small foreword: This might look like a cherrypy-oriented post, and should therefore go to the cherrypy group, but if you read to the end, you'll see it's a more basic python problem, with cherrypy only as an example. ;)
>From the decorator PEP (318) I get it that you can /add/ parameters to a call. Say you do something like this: @mydeco( foo="bar" ) def myfunc( hello ): print foo, foo However, this is not what I would like to do. I would like to take away one or more attributes using a decorator. My goal is to centralize the logic associated with that parameter. In my particular example, I am writing a cherrypy application (more specifically, turbogears1) and I would like all controller method to accept a "lang" and a "skin" attribute. As a simple, but hands-on example, imagine code like this (http://python.pastebin.com/f25f2429b): class MyController(Controller): @expose() def index(self, skin="default", lang="en"): set_skin( skin ) set_language( lang ) return "Hello skinned world" @expose() def foo(self, skin="default", lang="en"): set_skin( skin ) set_language( lang ) return "bar" This becomes cumbersome however for a large application with many controllers and methods. Always adding the parameters to the methods and function calls into the method bodies looks way to repetitive for my taste. Currently I solve this by using a cherrypy filter which removes those parameters from the HTTP-Request and puts them into the session object. This looked wrong to me though right from the start. Also, the cherrypy docs advise against the use of "filters" for application logic. But this looks pretty much like that to me.... somewhat. Worse yet, filters are not supported in Turbogears2 any longer. Which makes porting my app not straight-forward, as I have to port my filters and write WSGI middleware instead. I would prefer a syntax like this (http://python.pastebin.com/ f462bc29c) class MyController(Controller): @expose() @skinnable @translatable def index(self): return "Hello skinned world" @expose() @skinnable @translatable def foo(self): return "bar" This, to me has several advantages: The logic is "encapsulated" in the application code itself. I do not need to rely on framework specific features (be it cherrypy or wsgi). This would make the application more self-contained and hence more future proof. But right here lies my problem. If you are not familiar with CherryPy, let me digress for a tiny bit to give you the necessary backgroud: Inside a controller, an "exposed" method is reachable via HTTP requests. It's possible to force request parameters. If that is the case (as in my case it is), then the call will only be successful, if all parameters received a vaule and no unknown parameters have been passed. Assume the following signature: def index(self) This will successfully return an HTTP Response when the client requested the resource on the URL "/index". If the client adds a query string, say "/index?lang=en" the call will *fail* as this parameter is unkown. For this to work the signature must read: def index(self, lang) or def index(self, lang="en") Right.... end of digression, back to topic: My ultimate question is: Is it possible to write a decorator that removes a parameter from a call and return a function without that parameter? Something along the lines (http://python.pastebin.com/ f257877cd): def translatable(f): "Note that this code is only an example and will not work!" lang = f.__get_parameter_value__("lang") f.__remove_parameter__("lang") do_something_with_lang(lang) return f I am aware, that this depends on *when* the decorator call is executed. If its called whenever the decorated function is called, then there should be some way to handle this. If it's called at "compile-time", then I suppose it's not going to be possible. A usage scenario would be this: # --- definition --------------- @translatable def index(self): return _("Hello", lang) # --- call ---------------------- obj.index( lang="de") obj.index() As you can see, the method definition does not contain the "lang" parameter in the signature, but I want to be able to (optionally) set it during a call. I hope I made my ideas clear enough. I would be very positively surprised if this worked. It would make my application code much easier to read, understand and follow. The filters currently do a lot of magic "behind-the-scenes" and if somebody else needs to jump in and code on that application they will surely ask themselves "where the ****** is that ***** lang variable set?" :) And I'd like to make it as easy as possible for everyone :) Or, maybe you even have a better solution in mind? I'm open for suggestions. -- http://mail.python.org/mailman/listinfo/python-list