Steve Crook
Steve Crook

Reputation: 1055

Python Classes and Iteration

I'm using the standard Python mailbox module to read messages from a Maildir. Once read, I parse them and store the results in a dict. I've put this functionality into a class and use __getitems__ to enable other components of my program to access them. This works nicely and I'm happy that my code is both functional and readable.

My problem is how to turn this from a class that parses one message at a time into something that iterates over each message in the Maildir. One easy solution is to put a for loop in the main program and use the mailbox.iterkeys:

inbox = mailbox.Maildir('Maildir')
for key in inbox.iterkeys():
    mailparse.process(inbox, key)

This works but to me it doesn't seem very neat. I'd expect to have all the maildir related functionality within the class rather than having to pass each maildir key into it. Something like:

class mailparse():
    def __init__(self, mdirpath):
        inbox = mailbox.Maildir(mdirpath)

    def __getitems__(self, key):
        return self.dictionary[key]

    def process():
        for key in inbox.iterkeys()
            ....

for x in Mailprocess:
    ....

Obviously my above code doesn't work but I'm thinking there must a solution along these lines to entirely self-contain the block of functionality within the class.

Upvotes: 1

Views: 288

Answers (2)

Fred Foo
Fred Foo

Reputation: 363817

I'd set this up very differently. If you really want an iterable class to handle this,

class MailboxParser(object):
    def __init__(self, mbox):
        self.mbox = mbox

    def __getitem__(self, key):
        return self._process(key, self.mbox[key])

    def __iter__(self):
        for key, val in self.mbox.iteritems():
            yield self._process(key, val)

    def _process(self, key, content):
        """Do whatever on a single message"""

The __iter__ member allows you to do

for x in MailboxParser(mbox):
    # now x is the result of processing a single message

Upvotes: 3

Cédric Julien
Cédric Julien

Reputation: 80851

You could try to make a derivated class from Maildir :

class Mailparse(mailbox.Maildir):
    def process(self):
       for key in self.itertkeys():
          # do what you need with your key...

my_mailparser = Mailparse('Maildir')
my_mailparser.process()

you will use it like a mailbox.Maildir except that it has a new method process that will do... whatever you need to do with all the keys ;)

Upvotes: 0

Related Questions