Mangle function name with decorator?

Aaron Brady 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):
>     @GET
>     def new(self):
>         # Display the form to create a new foo
>
>     @POST
>     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 mailing list