Can I use decorators to manipulate return type or create methods?

Diez B. Roggisch deets at nospam.web.de
Thu Oct 19 11:52:36 EDT 2006


WakeBdr schrieb:
> I'm writing a class that will query a database for some data and return
> the result to the caller.  I need to be able to return the result of
> the query in several different ways: list, xml, dictionary, etc.  I was
> wondering if I can use decorators to accomplish this.
> 
> For instance, I have the following method
> 
> def getUsers(self, params):
>     return users.query(dbc)
> 
> To get the appropriate return types, I also have these methods.  I have
> these convenience methods for every query method in my class.
> 
> def getUsersAsXML(self, params):
>     return self._toXML(self.getUsers(params))
> def getUsersAsDict(self, params):
>     return self._toDict(self.getUsers(params))
> def getUsersAsList(self, params):
>     return self._toList(self.getUsers(params))
> 
> Instead of creating these three methods for every query method, is
> there a way to use decorators to manipulate the return type.  I'd still
> like to have the caller use getUsersAsXML, I just don't want to write
> the AsXML methods for every query method.  So the decorator would
> essentially create the convenience methods instead of me coding them.
> 
> One solution that I don't want to use is passing a variable into the
> query method that determines the return type.  This is what I don't
> want to do.
> def getUsers(self, params, returnType):
> 
> Any ideas on how I can accomplish this?

Use a metaclass.

class Magic(type):
     def __new__(cls, name, bases, d):
         for name, function in d.items():
             try:
                 function._marked
                 def toXML(self, *args, **kwargs):
                     return self._toXML(function(self, *args, **kwargs))
                 def toFOO(self, *args, **kwargs):
                     return self._toFOO(function(self, *args, **kwargs))
                 d[name + "XML"] = toXML
                 d[name + "FOO"] = toFOO
             except AttributeError:
                 pass
         return type(name, bases, d)


def mark(f):
     f._marked = True
     return f

class MyClass(object):
     __metaclass__ = Magic

     def _toXML(self, value):
         return "Look Ma, its XML! %r" % value

     def _toFOO(self, value):
         return "Look Ma, its FOO! %r" % value


     @mark
     def someMethod(self):
         return "Its the data, son"


o = MyClass()

print o.someMethod()
print o.someMethodXML()
print o.someMethodFOO()



Diez



More information about the Python-list mailing list