Mangle function name with decorator?
castironpi at gmail.com
Tue Mar 17 18:49:27 CET 2009
On Mar 17, 12:20 pm, Adam <adam.crossl... at gmail.com> wrote:
> Thanks, Andrew. I'm trying to accomplish something with a
> metaprogramming flavor, where, for the convenience of the programmer
> and the clarity of code, I'd like to have a decorator or some other
> mechanism do twiddling behind the scenes to make a class do something
> it wouldn't normally do.
> Here's a less-obfuscated exmaple: I want to build a framework for
> creating MVC web applications in Python (I know, I know, there's
> already 2^1bazillion of them) where a controller class can have
> methods that respond to the same action but for different HTTP verbs:
> class foo_controller(Controller):
> def new(self):
> # Display the form to create a new foo
> def new(self):
> # Receive a form post with new foo data in it
> The Controller class will do all of the work behind the scenes to
> makes sure that the correct method is called at run-time, but for the
> sake of the programmer, I'd like to supply a clear, friendly syntax
> like this. Without a little metaprogramming magic, last-in-wins, and
> only the second version of foo will end up in the class, so I'd like
> to mangle the names to something that will result in a unique
> attribute name and that the Controller class can work with behind the
> scenes to do the right thing at run time.
> So, Python experts, am I completely barking up the wrong tree here?
Unfortunately, your target is out of range for decorators. Decorators
can only do:
a= foo( a )
You want something like:
a_jam= foo( a )
However, metaclasses, possibly -combined- with decorators, may fit the
bill. When the class is being constructed, and is just a string, a
tuple of bases and a dictionary, you can intercept the call to 'type',
and modify the dictionary.
You would need a unique attribute to look for on values in the
dictionary, which means you'd need to detect what functions you are
renaming; possibly by using a decorator to mark them. (Untested:)
class X( metaclass= M ):
@mark( 'A' )
def foo( ... ).
class M( type ):
def __new__( cls, name, bases, namespace ):
for k, v in namespace.items():
if v.tag== 'mark-A':
namespace[ k ]= modification( v )
or in your case:
del namespace[ k ]
namespace[ k_mod ]= v.original
possibly also setting func_name as well.
return type( name, bases, namespace )
More information about the Python-list