Mangle function name with decorator?
Adam
adam.crossland at gmail.com
Wed Mar 18 09:47:56 EDT 2009
On Mar 17, 1:49 pm, Aaron Brady <castiro... at gmail.com> wrote:
> 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 )
I tried this, but unfortunately, it still doesn't allow me to have two
methods that initially have the same name, because the namespace
dictionary that the metaclass gets only has one one entry, the last
one in. So, if I try code like this:
def get_only(action):
setattr(action, "get_only", True)
return action
class ControllerMetaclass(type):
def __new__(cls, name, bases, namespace):
print str(namespace)
for k, v in namespace.items():
if hasattr(v, "get_only"):
new_name = "_get_" + k
print "new_name is " + new_name
del namespace[k]
namespace[new_name] = v
v.__name__ = new_name
return type(name, bases, namespace)
class Controller(object):
def __call__(self):
if (self.method != None):
get_mangled_name = "_" + self.method + "_" + self.action
if hasattr(self, get_mangled_name):
method = getattr(self, get_mangled_name)
return method()
else:
if hasattr(self, self.action):
return getattr(self, self.action)()
else:
raise NotImplementedError
else:
if hasattr(self, self.action):
return getattr(self, self.action)()
else:
raise NotImplementedError
class foo_controller(Controller):
__metaclass__= ControllerMetaclass
def __init__(self, action, method = None):
self.action = action
self.method = method
def foo(self):
print "in foo()"
@get_only
def foo(self):
print "in get_only foo()"
def bar(self):
print "in bar()"
a = foo_controller("foo", "get")
a()
b = foo_controller("foo")
print dir(b)
b()
c = foo_controller("bar","get")
c()
The first definition of foo (the one that is not decorated) is over-
written by the second one, and the metaclass never sees it. So, I
think that I understand what you said about storing the functions in a
hashtable. That makes sense, as I can keep a reference to the
function even if ti gets over-written in the class main namespace
dictionary. However, I'm not entirely sure about how to do that with
decorators. Wouldn't the decorator function have to be bound to a
context to keep a hastable between calls? I can't us a bound method
as a decorator, can I?
More information about the Python-list
mailing list