472,993 Members | 2,576 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,993 software developers and data experts.

Question about email-handling modules

Hello,

I'm new to Python but have lots of programming experience in C, C++ and
Perl. Browsing through the docs, the email handling modules caught my eye
because I'd always wanted to write a script to handle my huge, ancient, and
partially corrupted email archives.

Of course I know that this kind of project shouldn't be tackled by a
beginner in a language, but I still thought I'd give it a spin.

So I wrote the stuff at the bottom. It lists senders, subjects and
addressees of all messages in an mbox.

Things that I don't understand:

1. Why can I get the 'subject' and 'from' header field unsig the []
notation, but not 'to'? When I print Message.keys I get a list of all header
fields of the message, including 'to'. What's the difference between
message['to'] and message.get('to')?

2. Why can't I call the get_payload() method on the message? What I get is
this cryptic error: "AttributeError: Message instance has no attribute
'get_payload'". I'm trying to call a method here, not an attribute. It makes
no difference if I put parentheses after get_payload or not. I looked into
the email/Message module and found get_payload defined there.

I don't want to waste your time by requesting that you pick apart my silly
example. But maybe you can give me a pointer in the right direction. This is
python 2.4 on a Debian box.

---------------------------

#!/usr/bin/python
import mailbox
import email # doesn't make a difference
from email import Message # neither does this

mbox = file("mail.old/friends")

for message in mailbox.UnixMailbox(mbox):
subject = message['subject']
frm = message['from']
# to = message['to'] # this throws a "Key Error"
to = message.get('to'); # ...but this works
print frm, "writes about", subject, "to", to
# print message.get_payload() # this doesn't work

--------------------------

robert
Dec 20 '07 #1
5 1241
Robert Latest wrote:
Hello,

I'm new to Python but have lots of programming experience in C, C++ and
Perl. Browsing through the docs, the email handling modules caught my eye
because I'd always wanted to write a script to handle my huge, ancient, and
partially corrupted email archives.

Of course I know that this kind of project shouldn't be tackled by a
beginner in a language, but I still thought I'd give it a spin.

So I wrote the stuff at the bottom. It lists senders, subjects and
addressees of all messages in an mbox.

Things that I don't understand:

1. Why can I get the 'subject' and 'from' header field unsig the []
notation, but not 'to'? When I print Message.keys I get a list of all header
fields of the message, including 'to'. What's the difference between
message['to'] and message.get('to')?
On dicts, and presumably on Messages too, .get returns a default value
(None, or you can specify another with .get("key", "default") if the key
doesn't exist.

I can't say why ['to'] doesn't work when it's in the list of keys, though.
2. Why can't I call the get_payload() method on the message? What I get is
this cryptic error: "AttributeError: Message instance has no attribute
'get_payload'". I'm trying to call a method here, not an attribute. It makes
no difference if I put parentheses after get_payload or not. I looked into
the email/Message module and found get_payload defined there.
Methods are attributes. When you do "obj.method()", "obj.method" and
"()" are really two separate things: It gets the "method" attribute of
"obj", and then calls it.
I don't want to waste your time by requesting that you pick apart my silly
example. But maybe you can give me a pointer in the right direction. This is
python 2.4 on a Debian box.

---------------------------

#!/usr/bin/python
import mailbox
import email # doesn't make a difference
from email import Message # neither does this

mbox = file("mail.old/friends")

for message in mailbox.UnixMailbox(mbox):
subject = message['subject']
frm = message['from']
# to = message['to'] # this throws a "Key Error"
to = message.get('to'); # ...but this works
print frm, "writes about", subject, "to", to
# print message.get_payload() # this doesn't work

--------------------------

robert
(Oops, I wrote this like half an hour ago, but I never sent it.)
--
Dec 20 '07 #2
On Thu, 20 Dec 2007 09:31:10 +0000, Robert Latest wrote:
1. Why can I get the 'subject' and 'from' header field unsig the []
notation, but not 'to'? When I print Message.keys I get a list of all
header fields of the message, including 'to'. What's the difference
between message['to'] and message.get('to')?
message['to'] looks up the key 'to', raising an exception if it doesn't
exist. message.get('to') looks up the key and returns a default value if
it doesn't exist.

See help(message.get) for more detail.

2. Why can't I call the get_payload() method on the message? What I get
is this cryptic error: "AttributeError: Message instance has no
attribute 'get_payload'". I'm trying to call a method here, not an
attribute. It makes no difference if I put parentheses after get_payload
or not. I looked into the email/Message module and found get_payload
defined there.
All methods are attributes (although the opposite is not the case), so if
a method doesn't exist, you will get an AttributeError.

The email.Message.Message class has a get_payload, but you're not using
that class. You're using mailbox.UnixMailbox, which returns an instance
of rfc822.Message which *doesn't* have a get_payload method.

Damned if I can work out how to actually *use* the email module to read
an mbox mail box. I might have to RTFM :(

http://docs.python.org/lib/module-email.html
http://docs.python.org/lib/module-mailbox.html
*later*

Ah! The Fine Manual is some help after all. Try this:

# copied from http://docs.python.org/lib/mailbox-deprecated.html
import email
import email.Errors
import mailbox
def msgfactory(fp):
try:
return email.message_from_file(fp)
except email.Errors.MessageParseError:
# Don't return None since that will
# stop the mailbox iterator
return ''

fp = file('mymailbox', 'rb')
mbox = mailbox.UnixMailbox(fp, msgfactory)
for message in mbox:
print message.get_payload()

But note that message.get_payload() will return either a string (for
single part emails) or a list of Messages (for multi-part messages).
--
Steven
Dec 20 '07 #3
Steven D'Aprano <st***@remove-this-cybersource.com.auwrote:
On Thu, 20 Dec 2007 09:31:10 +0000, Robert Latest wrote:
[snip most of question and helpful answer]
>
But note that message.get_payload() will return either a string (for
single part emails) or a list of Messages (for multi-part messages).
Note also that the mailbox module in python 2.5 is quite unlike the
mailbox module in python 2.4 so code written for the 2.4 mailbox will
be most unlikely to work under 2.5 without at least some changes.

At least that's my experience/understanding.

Also, from the way things currently work in the 2.5 version I think
there will (hopefully) be some more quite significant changes.

--
Chris Green
Dec 20 '07 #4
Steven D'Aprano wrote:
message['to'] looks up the key 'to', raising an exception if it doesn't
exist. message.get('to') looks up the key and returns a default value if
it doesn't exist.
Ah, so the [] notation got hung up on some message right at the beginning
and didn't even let the script continue. Makes sense.
All methods are attributes (although the opposite is not the case), so if
a method doesn't exist, you will get an AttributeError.
I see. I've already gathered that Python likes to use different words for
common things (attribute instead of member or method).
Damned if I can work out how to actually *use* the email module to read
an mbox mail box. I might have to RTFM :(
Yeah, I think I haven't picked the right module to get started with.
But note that message.get_payload() will return either a string (for
single part emails) or a list of Messages (for multi-part messages).
Yes, I did note that.

Thanks for the tips (also to the others who have answered).

Python looks like fun though. Maybe I should try to tackle some other
problem first.

robert
Dec 20 '07 #5
On Dec 20, 4:15 pm, Robert Latest <boblat...@yahoo.comwrote:
Steven D'Aprano wrote:
[...]
All methods are attributes (although the opposite is not the case), so if
a method doesn't exist, you will get an AttributeError.

I see. I've already gathered that Python likes to use different words for
common things (attribute instead of member or method).
...we were hoping it would make you feel comfy when coming from
Perl ;-)

On a more serious note, Python is actually quite semantically regular:
a dot (.) always means the same thing, as do parens. It might not be
immediately obvious exactly _what_ it means if you're coming from
languages that confuse issues with syntactic sweetness.

When you see code that says

foo.bar(baz)

there are two distinct operations happening, namely

tmp = foo.bar # attribute lookup (the dot-operator)
tmp(baz) # function call (the paren-operator)

this will give you the insight to one of the first optimization
methods you can use if a loop is a bottleneck

for i in range(100000):
foo.bar(i) # profiling says this is a bottleneck

attribute lookup hoisting optimization

tmp = foo.bar # move attribute lookup outside the loop
for i in range(100000):
tmp(i)

in the interest of full disclosure, I should probably mention that I'm
of course lying to you ;-) You can override both attribute lookup and
function call in your own classes, but (a) that shouldn't be important
to you at this point *wink*, and (b) at that level Python is quite
semantically regular.

-- bjorn
Dec 21 '07 #6

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

Similar topics

5
by: sea | last post by:
I have 2 applications, one a Microsoft Visual Basic application and the other a Java application both connecting to the same DB2 database. The database has binary LOB objects. The Visual Basic...
3
by: Ekqvist Marko | last post by:
Hi, I have one Access database table including questions and answers. Now I need to give answer id automatically to questionID column. But I don't know how it is best (fastest) to do? table...
8
by: Hardy Wang | last post by:
Hi: Is it possible for me to create/open web application from remote machine other than port 80? And create application directly under virtual web site instead of creating a virtual directory?...
2
by: akshayrao | last post by:
could someone point me in the right direction regarding this question?? http://groups.google.com/group/programpara/browse_thread/thread/75b58c897f890930 thanks.
29
by: MP | last post by:
Greets, context: vb6/ado/.mdb/jet 4.0 (no access)/sql beginning learner, first database, planning stages (I think the underlying question here is whether to normalize or not to normalize this...
56
by: spibou | last post by:
In the statement "a *= expression" is expression assumed to be parenthesized ? For example if I write "a *= b+c" is this the same as "a = a * (b+c)" or "a = a * b+c" ?
13
by: Eric_Dexter | last post by:
All I am after realy is to change this reline = re.line.split('instr', '/d$') into something that grabs any line with instr in it take all the numbers and then grab any comment that may or may...
4
by: =?Utf-8?B?Um9iIE1pbGxtYW4=?= | last post by:
I am developing a C# client app using VS 2008 that consumes a 3rd party web service. My question is how/where in my IDE/Debugging session can I visually see the actual XML message that is being...
25
by: Thomas R. Hummel | last post by:
I'm going to try to describe this situation as best as I can, but if anything is unclear please let me know. Some of this database was already in place before I arrived on the scene, and I don't...
56
by: mdh | last post by:
As I begin to write more little programs without the help of the exercises, little things pop up that I need to understand more fully. Thus, below, and although this is not the exact code, the...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
SueHopson
by: SueHopson | last post by:
Hi All, I'm trying to create a single code (run off a button that calls the Private Sub) for our parts list report that will allow the user to filter by either/both PartVendor and PartType. On...

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.