首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用windows python 2.3进行的poplib重构

使用windows python 2.3进行的poplib重构
EN

Stack Overflow用户
提问于 2018-09-06 05:00:55
回答 2查看 0关注 0票数 0

嗨,伙计们,请你帮我重构一下,这样它才是明智的pythonic。

代码语言:javascript
复制
import sys
import poplib
import string
import StringIO, rfc822
import datetime
import logging

def _dump_pop_emails(self):
    self.logger.info("open pop account %s with username: %s" % (self.account[0], self.account[1]))
    self.popinstance = poplib.POP3(self.account[0])
    self.logger.info(self.popinstance.getwelcome()) 
    self.popinstance.user(self.account[1])
    self.popinstance.pass_(self.account[2])
    try:
        (numMsgs, totalSize) = self.popinstance.stat()
        for thisNum in range(1, numMsgs+1):
            (server_msg, body, octets) = self.popinstance.retr(thisNum)
            text = string.join(body, '\n')
            mesg = StringIO.StringIO(text)                               
            msg = rfc822.Message(mesg)
            name, email = msg.getaddr("From")
            emailpath = str(self._emailpath + self._inboxfolder + "\\" + email + "_" + msg.getheader("Subject") + ".eml")
            emailpath = self._replace_whitespace(emailpath)
            file = open(emailpath,"wb")
            file.write(text)
            file.close()
            self.popinstance.dele(thisNum)
    finally:
        self.logger.info(self.popinstance.quit())

def _replace_whitespace(self,name):
    name = str(name)
    return name.replace(" ", "_")   

同样在_replace_whitespace方法中,我希望有一些清理程序,它可以取出所有可能导致处理的非法字符。

基本上我想以标准方式将电子邮件写入收件箱目录。

我在这里做错了吗?

EN

回答 2

Stack Overflow用户

发布于 2018-09-06 13:53:16

这不是重构(据我所知,它不需要重构),但有些建议:

您应该使用电子邮件包而不是rfc822。用email.Message替换rfc822.Message,并使用email.Utils.parseaddr(msg [“From”])获取名称和电子邮件地址,并使用msg [“Subject”]来获取主题。

使用os.path.join创建路径。这个:

代码语言:javascript
复制
emailpath = str(self._emailpath + self._inboxfolder + "\\" + email + "_" + msg.getheader("Subject") + ".eml")

变为:

代码语言:javascript
复制
emailpath = os.path.join(self._emailpath + self._inboxfolder, email + "_" + msg.getheader("Subject") + ".eml")

(如果self._inboxfolder以斜杠开头,或者self._emailpath以一个结束,则可以用逗号替换第一个+)。

它并没有真正伤害任何东西,但你可能不应该使用“file”作为变量名称,因为它会影响内置类型(像pylint或pychecker这样的检查器会警告你)。

如果你没有在这个函数之外使用self.popinstance(假设你在函数中连接和退出似乎不太可能),那么就没有必要将它作为self的属性。只需单独使用“popinstance”即可。

使用xrange而不是range。

而不是只导入StringIO,执行以下操作:

代码语言:javascript
复制
try:
    import cStringIO as StringIO
except ImportError:
    import StringIO

如果这是一个可以由多个客户端一次访问的POP邮箱,则可能需要在RETR调用周围放置一个try / except,以便在无法检索一条消息时继续。

正如约翰所说,使用“\ n”.join而不是string.join,使用try / finally仅在文件打开时关闭文件,并单独传递日志记录参数。

我能想到的一个重构问题是你不需要解析整个消息,因为你只是转储原始字节的副本,而你想要的只是From和Subject标题。您可以使用popinstance.top(0)来获取标题,从中创建消息(空白正文),并将其用于标题。然后执行完整的RETR以获取字节。如果您的消息很大(这样解析它们需要很长时间),这只会值得做。在进行此优化之前,我肯定会测量。

对于您的名称清理功能,它取决于您希望名称有多好,以及您确定电子邮件和主题使文件名唯一(看起来不太可能)。你可以这样做:

代码语言:javascript
复制
emailpath = "".join([c for c in emailpath if c in (string.letters + string.digits + "_ ")])

而你最终只会使用字母数字字符和下划线和空格,这看起来像一个可读的集合。鉴于您的文件系统(使用Windows)可能不区分大小写,您也可以小写(在末尾添加.lower())。如果你想要更复杂的东西,你可以使用emailpath.translate。

票数 0
EN

Stack Overflow用户

发布于 2018-09-06 14:35:40

继续我对约翰回答的评论

我发现问题是什么,名称字段和主题字段中存在非法字符,这导致python在看到“:”和“/”之后尝试将电子邮件写为目录,从而导致打嗝。

约翰点4号无效!所以我像以前一样离开了。也是第1点正确,我是否正确实施了您的建议?

代码语言:javascript
复制
def _dump_pop_emails(self):
    self.logger.info("open pop account %s with username: %s", self.account[0], self.account[1])
    self.popinstance = poplib.POP3(self.account[0])
    self.logger.info(self.popinstance.getwelcome()) 
    self.popinstance.user(self.account[1])
    self.popinstance.pass_(self.account[2])
    try:
        (numMsgs, totalSize) = self.popinstance.stat()
        for thisNum in range(1, numMsgs+1):
            (server_msg, body, octets) = self.popinstance.retr(thisNum)
            text = '\n'.join(body)
            mesg = StringIO.StringIO(text)                               
            msg = rfc822.Message(mesg)
            name, email = msg.getaddr("From")
            emailpath = str(self._emailpath + self._inboxfolder + "\\" + self._sanitize_string(email + " " + msg.getheader("Subject") + ".eml"))
            emailpath = self._replace_whitespace(emailpath)
            print emailpath
            file = open(emailpath,"wb")
            file.write(text)
            file.close()
            self.popinstance.dele(thisNum)
    finally:
        self.logger.info(self.popinstance.quit())

def _replace_whitespace(self,name):
    name = str(name)
    return name.replace(" ", "_")   

def _sanitize_string(self,name):
    illegal_chars = ":", "/", "\\"
    name = str(name)
    for item in illegal_chars:
        name = name.replace(item, "_")
    return name
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100000731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档