Python 的 imaplib 是不是允许您设置超时?

Posted

技术标签:

【中文标题】Python 的 imaplib 是不是允许您设置超时?【英文标题】:Does Python's imaplib let you set a timeout?Python 的 imaplib 是否允许您设置超时? 【发布时间】:2014-08-16 20:18:20 【问题描述】:

我正在查看 Python 的 imaplib 的 API。

据我所知,没有办法像 smtplib 那样设置超时。

正确吗?如果您不想阻止它,您将如何处理无效的主机?

【问题讨论】:

【参考方案1】:

imaplib 模块不提供设置超时的方法,但您可以通过socket.setdefaulttimeout 为新的套接字连接设置默认超时:

import socket
import imaplib
socket.setdefaulttimeout(10)
imap = imaplib.IMAP4('test.com', 666)

或者您也可以使用imaplib source 和文档中的一些知识覆盖imaplib.IMAP4 类,从而提供更好的控制:

import imaplib
import socket

class IMAP(imaplib.IMAP4):
    def __init__(self, host='', port=imaplib.IMAP4_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_PORT):
        self.host = host
        self.port = port
        self.sock = socket.create_connection((host, port), timeout=self.timeout)
        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')

请注意,在创建连接后,我们应该将套接字超时设置回None,以使其进入阻塞模式以进行后续socket.makefile 调用,如方法文档中所述:

... 套接字必须处于阻塞模式(它不能有超时)。 ...

【讨论】:

请删除 self.sock.settimeout(None),它让超时不起作用并一直阻塞。【参考方案2】:
import imaplib
...
# ssl and timeout are config values
# connection to IMAP server
if ssl:
    imapResource = imaplib.IMAP4_SSL(server, port)
else:
    imapResource = imaplib.IMAP4(server, port)
# communications timeout
sock=imapResource.socket()
timeout = 60 * 5 # 5 minutes
sock.settimeout(timeout)

【讨论】:

【参考方案3】:

如果你想要IMAP4_SSL,我们可以修改 着名的garkin 的 答案是用 ssl 上下文 ssl_context.wrap_socket() 包装套接字

import imaplib
import socket

class IMAP(imaplib.IMAP4_SSL):
    def __init__(self, host='', port=imaplib.IMAP4_SSL_PORT, timeout=None):
        self.timeout = timeout
        # no super(), it's an old-style class
        imaplib.IMAP4_SSL.__init__(self, host, port)

    def open(self, host='', port=imaplib.IMAP4_SSL_PORT):

        sock = socket.create_connection((host, port), timeout=self.timeout)
        self.sock = self.ssl_context.wrap_socket(sock, server_hostname=host)

        # clear timeout for socket.makefile, needs blocking mode
        self.sock.settimeout(None)
        self.file = self.sock.makefile('rb')

【讨论】:

以上是关于Python 的 imaplib 是不是允许您设置超时?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python中执行IMAP搜索(使用Gmail和imaplib)?

使用 Python 和 imaplib 在 GMail 中移动电子邮件

Python imaplib 选择文件夹

如何使用 imaplib 创建电子邮件并将其发送到特定邮箱

如何使用 Python imaplib 为 IMAP (Gmail) 启用推送通知?

Python/imaplib - 如何获取消息的标签?