473,734 Members | 2,824 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))

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?

thanks

Oct 19 '06 #1
8 1643
On 19 Oct 2006 06:43:49 -0700, WakeBdr <bb***@optiosof tware.comwrote:
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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))

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?

You can't do it as fully magically as I'd like, because at the time
decorators are run, the methods are just functions and aren't bound as
methods yet (so you can't automagically add methods to the class, for
example - you'd need to do that after the class definition finishes
executing). You *could* decorate all the functions you want to have
special return types, then (after the class definition) loop through
those to generate the extra return funcs.

You can do it with a minimum of boilerplate this way:

from functools import wraps #only in 2.5, you can do this by hand in 2.4
#wrapped is the function we're calling and returning as XML
#xmlfunc is the stub function we're replacing
def returnXML(wrapp ed):
def f(xmlfunc):
@wraps(xmlfunc)
def xmlMethod(self) :
return self.asXML(wrap ped(self))
return xmlMethod
return f

class T(object):
def getUser(self):
return "user"
def asXML(self, data):
return "<xml>%s</xml>"%(data)
@returnXML(getU ser)
def getUserAsXML(se lf):pass

t = T()
print t.getUserAsXML( )
Oct 19 '06 #2
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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))

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._marke d
def toXML(self, *args, **kwargs):
return self._toXML(fun ction(self, *args, **kwargs))
def toFOO(self, *args, **kwargs):
return self._toFOO(fun ction(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
Oct 19 '06 #3
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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))

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__(sel f, name):
prefix, delim, suffix = name.rpartition ("_as_")
if prefix and suffix:
cls = self.__class__
inner = attrgetter(pref ix)
outer = attrgetter(deli m + suffix)
def wrapped(self, *args):
return outer(self)(inn er(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(nam e=%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
Oct 19 '06 #4
Diez,
What does the function._marke d 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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))

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._marke d
def toXML(self, *args, **kwargs):
return self._toXML(fun ction(self, *args, **kwargs))
def toFOO(self, *args, **kwargs):
return self._toFOO(fun ction(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
Oct 19 '06 #5
WakeBdr schrieb:
Diez,
What does the function._marke d accomplish?
Its a decorator that tells the metaclass which functions to provide with
a *XML/*FOO variant as well. I thought that was pretty obvious, given
the name "mark" and all that.

Diez
Oct 19 '06 #6
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.getUsersAsXM L(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._marke d 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(s elf, params):
return self._toXML(sel f.getUsers(para ms))
def getUsersAsDict( self, params):
return self._toDict(se lf.getUsers(par ams))
def getUsersAsList( self, params):
return self._toList(se lf.getUsers(par ams))
>
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._marke d
def toXML(self, *args, **kwargs):
return self._toXML(fun ction(self, *args, **kwargs))
def toFOO(self, *args, **kwargs):
return self._toFOO(fun ction(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
Oct 20 '06 #7
WakeBdr schrieb:
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.
You need to give a __metaclass__ to one of them, and I think they must
be new-style-classes.
Diez
Oct 20 '06 #8
OK, I think I'm close now. I just can't get past this one error. Here
is my code, followed by the output produced when I run it.

class Magic(type):
def __new__(cls, name, bases, d):
for name, function in d.items():
try:
function._marke d
print 'Class: %s' % cls
print 'Method: %s' % name
def toXML(self, *args, **kwargs):
return
self._toXML(fun ction(self, *args, **kwargs))
def toList(self, *args, **kwargs):
return
self._toList(fu nction(self, *args, **kwargs))
d[name+'XML'] = toXML
d[name+'List'] = toList
except AttributeError:
#traceback.prin t_exc()
pass
return type(name, bases, d)

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

class test(object):

def _toXML(self, value):
return '<xml>%s</xml>' % value
def _toList(self, value):
return '<list>%s</list>' % value

class testtest(test):

__metaclass__ = Magic

@mark
def printData(self, data):
return 'child-%s' % data
t = testtest()
print t.printData('da ta')
print t.printDataXML( 'data')
print t.printDataList ('data')

===========OUTP UT=========
Class: <class '__main__.Magic '>
Method: printData
child-data
Traceback (most recent call last):
File "test.py", line 43, in ?
print t.printDataXML( 'data')
File "test.py", line 11, in toXML
return self._toXML(fun ction(self, *args, **kwargs))
TypeError: __new__() takes exactly 4 arguments (3 given)

Diez B. Roggisch wrote:
WakeBdr schrieb:
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.

You need to give a __metaclass__ to one of them, and I think they must
be new-style-classes.
Diez
Oct 20 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2069
by: Michael Sparks | last post by:
Anyway... At Europython Guido discussed with everyone the outstanding issue with decorators and there was a clear majority in favour of having them, which was good. From where I was sitting it looked like about 20:20 split on the following syntaxes: 1 def func(arg1, arg2, arg3) : function... 2 def func(arg1, arg2, arg3): function...
1
1810
by: Stephen Thorne | last post by:
Decorators have been getting lots of air-time at the moment, but only really the syntax. After a short discussion on irc the other night I decided to download python2.4 from experimental and write out some truely worthy decorator hacks. I implemented multimethods as a warm-up, and then implemented tail call elimination. Presented here is a brief synopsis of both, and then the implementations....
2
1708
by: Guido van Rossum | last post by:
Robert and Python-dev, I've read the J2 proposal up and down several times, pondered all the issues, and slept on it for a night, and I still don't like it enough to accept it. The only reason to accept it would be to pacify the supporters of the proposal, and that just isn't a good enough reason in language design. However, it got pretty darn close! I'm impressed with how the community managed to pull together and face the enormous...
0
2349
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and Methods Version: $Revision: 1.34 $ Last-Modified: $Date: 2004/09/03 09:32:50 $ Author: Kevin D. Smith, Jim Jewett, Skip Montanaro, Anthony Baxter
3
1510
by: Bruce Cropley | last post by:
Hi all I'm trying to generate test methods in a unittest TestCase subclass, using decorators. I'd like to be able to say: class MyTestCase(unittest.TestCase): @genTests(, , ) def something(self, side, price, someFlag): # etc...
1
1140
by: birchb | last post by:
Guido has proposed a syntax for type annotations in Python-3000. Example: def foo(x: t1, y: t2) -> t3: ...body... http://www.artima.com/weblogs/viewpost.jsp?thread=87182 The types are dynamic and there is significant execution of code prior
5
2742
by: bayerj | last post by:
I want to make a registry of methods of a class during creation. My attempt was this """ classdecorators.py Author: Justin Bayer Creation Date: 2006-06-22 Copyright (c) 2006 Chess Pattern Soft, All rights reserved. """
2
1951
by: Andrew West | last post by:
Probably a bit of weird question. I realise decorators shouldn't be executed until the function they are defined with are called, but is there anyway for me to find all the decorates declared in a file when I import it? Or perhaps anyway to find the decorators by loading the file by other methods (with out simply parsing it by hand). Basically what I'm looking for is a way to, given a python file, look through that file and find all the...
0
1056
by: Gabriel Genellina | last post by:
En Tue, 29 Jul 2008 08:45:02 -0300, Themis Bourdenas <bourdenas@gmail.com> escribi�: In a very strict sense, I'd say that all those references to "method decorators" are wrong - because those "def" statements inside a "class" statement define functions, not methods. In that sense almost every Python programmer is wrong too: in this example class X:
0
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9236
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9182
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8186
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6031
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4809
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.