Can I use decorators to manipulate return type or create methods?
Peter Otten
__peter__ at web.de
Thu Oct 19 12:52:40 EDT 2006
WakeBdr wrote:
> 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?
Here's an odd approach, entirely based on naming conventions:
from operator import attrgetter
class Composer(object):
def __getattr__(self, name):
prefix, delim, suffix = name.rpartition("_as_")
if prefix and suffix:
cls = self.__class__
inner = attrgetter(prefix)
outer = attrgetter(delim + suffix)
def wrapped(self, *args):
return outer(self)(inner(self)(*args))
setattr(cls, name, wrapped)
return getattr(self, name)
raise AttributeError("sorry, no %r" % name)
class A(Composer):
def _as_xml(self, obj):
return "as_xml(%s)" % (obj,)
def _as_list(self, obj):
return "as_list(%s)" % (obj,)
def get_users(self):
return "get_users()"
class B(A):
def _as_list(self, obj):
return "AS_LIST(%s)" % (obj,)
def get_artist_as_a_young_man(self, name):
return "get_artist_as_a_young_man(name=%r)" % name
if __name__ == "__main__":
a = A()
b = B()
print a.get_users_as_list()
print b.get_users_as_list()
print a.get_users_as_xml()
print b.get_artist_as_a_young_man_as_xml("James")
print a.get_artist_as_a_young_man_as_xml("James") # AttributeError
Peter
More information about the Python-list
mailing list