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

WakeBdr bbull at optiosoftware.com
Thu Oct 19 22:59:54 EDT 2006


Diez,
I get what that accomplishes now, but I'm having problems in my
implementation.  I was able to write a standalone class that worked
correctly.  However, in my code the class that I need to exhibit this
functionality inherits from another class.  This seems to cause
problems when I attempt to implement you solution.

Let's say I have two classes that look like the following:

class Parent:
    def getUsers(self, params):
        raise 'Not implemented'

    def _toXML(self, result):
        return result.toXML()

    def _toList(self, result):
        return result.toList()

class Child(Parent):
    def getUsers(self, params):
        return users.query(dbc)


Caller object would say something like:
ch = Child()
ch.getUsersAsXML(params)

How would I implement your solution in this scenario.  I've tried
"marking" the parent method, "marking" the child method, "marking"
both, but nothing seems to work.

WakeBdr wrote:
> Diez,
>      What does the function._marked accomplish?
>
> Diez B. Roggisch wrote:
> > 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