Python的imaplib可以设置超时吗?

14 投票
3 回答
7876 浏览
提问于 2025-04-18 11:07

我在查看Python的imaplib这个库的文档。

根据我的了解,似乎没有像smtplib那样可以设置超时的功能。

这样说对吗?如果你不想让程序卡住,遇到一个无效的主机,你会怎么处理呢?

3 个回答

0

如果你想使用 IMAP4_SSL,我们可以对famousgarkin的回答做一些修改,方法是用 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')
4
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)

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

21

这个 imaplib 模块本身没有提供设置超时时间的方法,不过你可以通过 socket.setdefaulttimeout 来为新的 socket 连接设置一个默认的超时时间:

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

另外,你也可以通过一些对 imaplib.IMAP4 类的重写来实现,这需要你对 imaplib 的源代码 和文档有一些了解,这样可以更好地控制:

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')

需要注意的是,在创建连接之后,我们应该把 socket 的超时时间设置回 None,这样才能让它进入阻塞模式,以便后续调用 socket.makefile,正如方法文档中所说:

... socket 必须处于阻塞模式(不能有超时时间)。...

撰写回答