How to wrap a class's methods?
Mathias Waack
M.Waack at gmx.de
Thu Feb 17 15:30:49 EST 2005
Grant Edwards wrote:
> I want to subclass an IMAP connection so that most of the
> methods raise an exception if the returned status isn't 'OK'.
> This works, but there's got to be a way to do it that doesn't
> involve so much duplication:
>
> class MyImap4_ssl(imaplib.IMAP4_SSL):
>
> def login(*args):
> s,r = imaplib.IMAP4_SSL.login(*args)
> if s!='OK':
> raise NotOK((s,r))
> return r
>
> def list(*args):
> s,r = imaplib.IMAP4_SSL.list(*args)
> if s!='OK':
> raise NotOK((s,r))
> return r
>
> def search(*args):
> s,r = imaplib.IMAP4_SSL.search(*args)
> if s!='OK':
> raise NotOK((s,r))
> return r
>
> [and so on for another dozen methods]
How about using a delegator:
class Wrapper:
funcs = ("login", "list", "search")
def __init__(self, classobj):
self.__wrapped = classobj()
def __getattr__(self, attr):
if attr in Wrapper.funcs:
def f(*args):
f1 = getattr(self.__wrapped, attr)
s,r = f1(args)
if s != 'OK': raise NotOk((s,r))
return r
return f
# raise some exception here
imap = Wrapper(imaplib.IMAP4_SSL)
If you wrap all methods you can ignore the if-test. Instead of the
class object you can pass instances to the wrapper if you need
special arguments for initialization.
I don't like subclassing;)
Mathias
PS: note that we're wrapping the instance's methods, not the class's
methods!
More information about the Python-list
mailing list