Python网络编程:E-mail服务(四) 编写传统邮件
2015-04-25 18:36
399 查看
简介
本文通过标准Python库的email模块提供MIMEText类,进行传统email的编写,从而对email模块有一个初步的认识。邮件编写
RFC 822定义了邮件的标准格式,在前面的文章对此也进行了相关介绍,这里我们通过MIMEText类,来编写一个传统邮件。''' Created on Apr 18, 2015 @author: jliu ''' from email.Utils import formatdate, make_msgid from email.mime.text import MIMEText if __name__ == '__main__': message = '''Hello,\n this is an autotest email.\n---Jinguang Liu.\n''' msg = MIMEText(message) msg['To'] = 'jinguang.liu@qq.com' msg['From'] = 'jliu@163.com' msg['Subject'] = 'This is a test email' msg['Date'] = formatdate(localtime=1) msg['Message-ID'] = make_msgid() print msg.as_string()查看一下程序运行的结果:
Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit To: jinguang.liu@qq.com From: jliu@163.com Subject: This is a test email Date: Sat, 25 Apr 2015 17:50:12 +0800 Message-ID: <20150425095012.3420.48931@bob-PC> Hello, this is an autotest email. ---Jinguang Liu.
代码解析
MIMEText类是用来创建文本类型的MIME对象,其类的实现如下:class MIMEText(MIMENonMultipart): """Class for generating text/* type MIME documents.""" def __init__(self, _text, _subtype='plain', _charset='us-ascii'): """Create a text/* type MIME document. _text is the string for this message object. _subtype is the MIME sub content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type header. This defaults to "us-ascii". Note that as a side-effect, the Content-Transfer-Encoding header will also be set. """ MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) self.set_payload(_text, _charset)MIMEText继承MIMENonMultipart类,实现单非多部分邮件的编写。_text参数是作为负载的字符串,_subtype是子类型,缺省设置为plain类型的纯文本文件。_charset是字符编码。除非显示的讲_charset设置为None, 否则MIMEText对象会创建Content-Type和Content-Transfer-Encoding的头部。从上面的运行结果中可以看出这点。
添加头部非常简单,按照msg['To'] = 'jinguang.liu@qq.com'格式很容易的就可以添加。这部分的工作是在基类Message中实现的,通过list类模拟字典功能,下面列出了源码中的相关实现:
class Message: """Basic message object. A message object is defined as something that has a bunch of RFC 2822 headers and a payload. It may optionally have an envelope header (a.k.a. Unix-From or From_ header). If the message is a container (i.e. a multipart or a message/rfc822), then the payload is a list of Message objects, otherwise it is a string. Message objects implement part of the `mapping' interface, which assumes there is exactly one occurrence of the header per message. Some headers do in fact appear multiple times (e.g. Received) and for those headers, you must use the explicit API to set or get all the headers. Not all of the mapping methods are implemented. """ def __init__(self): self._headers = [] self._unixfrom = None self._payload = None self._charset = None # Defaults for multipart messages self.preamble = self.epilogue = None self.defects = [] # Default content type self._default_type = 'text/plain' # # MAPPING INTERFACE (partial) # def __len__(self): """Return the total number of headers, including duplicates.""" return len(self._headers) def __getitem__(self, name): """Get a header value. Return None if the header is missing instead of raising an exception. Note that if the header appeared multiple times, exactly which occurrence gets returned is undefined. Use get_all() to get all the values matching a header field name. """ return self.get(name) def __setitem__(self, name, val): """Set the value of a header. Note: this does not overwrite an existing header with the same field name. Use __delitem__() first to delete any existing headers. """ self._headers.append((name, val)) def __delitem__(self, name): """Delete all occurrences of a header, if present. Does not raise an exception if the header is missing. """ name = name.lower() newheaders = [] for k, v in self._headers: if k.lower() != name: newheaders.append((k, v)) self._headers = newheaders def __contains__(self, name): return name.lower() in [k.lower() for k, v in self._headers] def has_key(self, name): """Return true if the message contains the header.""" missing = object() return self.get(name, missing) is not missing def keys(self): """Return a list of all the message's header field names. These will be sorted in the order they appeared in the original message, or were added to the message, and may contain duplicates. Any fields deleted and re-inserted are always appended to the header list. """ return [k for k, v in self._headers] def values(self): """Return a list of all the message's header values. These will be sorted in the order they appeared in the original message, or were added to the message, and may contain duplicates. Any fields deleted and re-inserted are always appended to the header list. """ return [v for k, v in self._headers] def items(self): """Get all the message's header fields and values. These will be sorted in the order they appeared in the original message, or were added to the message, and may contain duplicates. Any fields deleted and re-inserted are always appended to the header list. """ return self._headers[:] def get(self, name, failobj=None): """Get a header value. Like __getitem__() but return failobj instead of None when the field is missing. """ name = name.lower() for k, v in self._headers: if k.lower() == name: return v return failobj
在这个传统邮件编写的例子中,还使用了email.utils提供了两个方法来增加Date和Message-ID两个头部:
formatdate([timeval[, localtime][, usegmt]]) :返回RFC 28822(替代RFC 822)定义的日期字符串,格式:Fri, 09 Nov 2001 01:08:47 -0000
make_msgid([idstring]):返回与RFC 2822兼容的Message-ID字符串
最后,通过as_string()方法,可以获取邮件的字符串。
总结
通过email模块的MIMEText类来实现传统邮件的编写,并介绍了email相关类、接口的实现和使用。通过本文的介绍,读者应该比较容易的写出纯文本格式的邮件。相关文章推荐
- Python网络编程:E-mail服务(九) 发送HTML格式邮件
- Python网络编程:E-mail服务(二)传统E-mail格式
- Python网络编程:E-mail服务(八) 实现抄送和密送功能
- Python网络编程:E-mail服务(五)深入理解email模块的message和MIME类
- Python网络编程:E-mail服务(三)MIME解析
- Python网络编程:E-mail服务(五)深入理解email模块的message和MIME类
- Python网络编程:E-mail服务(三)MIME解析
- Python网络编程:E-mail服务(一)原理篇
- Python简单学习(lecture7)CGI编程、MySQL、网络编程、SMTP发送邮件
- 使用python3.0 编写C/S程序,初识wangpython的网络编程
- Java网络编程之JavaMail发送邮件和接受邮件
- Python 网络编程---简单的服务器与客户端实现---阻塞式编写
- socket 网络编程快速入门(一)教你编写基于UDP/TCP的服务(客户端)通信
- Java网络编程之JavaMail发送邮件和接受邮件
- [python&php 网络编程]通过端口号获取服务名
- Python3抓取页面信息,网络编程,简单发送QQ邮件
- Java网络编程之JavaMail发送邮件和接受邮件
- 利用Python的SocketServer框架编写网络服务程序
- Python 网络爬虫 005 (编程) 如何编写一个可以 下载(或叫:爬取)一个网页 的网络爬虫
- 利用Python的SocketServer框架编写网络服务程序