使用Python smtplib从Gmail发送带附件邮件时遇"LazyImporter object is not callable"错误
解决smtplib发送Gmail带附件邮件时的"LazyImporter' object is not callable"错误
嘿,我之前也踩过这个坑!这个错误其实是因为你用了旧版本的email模块导入方式,在Python 3的新版email库中,那些直接从email根模块导入的子模块已经变成了LazyImporter对象,没法直接调用啦。
问题根源
你原来的导入语句比如from email import MIMEBase、from email import Encoders都是Python 2时代的写法,在新版Python中已经被弃用,对应的模块现在都放在email.mime子目录下,而且Encoders也改成了小写的encoders。
修正方案
1. 替换过时的导入语句
把原来的导入换成下面的正确写法:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders import os
2. 完善完整的发送邮件函数
我帮你补全并修正了整个send_email函数,确保逻辑完整且符合新版库的要求:
def send_email(to, subject, text, filenames): try: gmail_user = 'xx@gmail.com' gmail_pwd = 'xxxx' # 创建多部分邮件容器,用于容纳正文和附件 msg = MIMEMultipart() msg['From'] = gmail_user msg['To'] = to msg['Subject'] = subject # 添加纯文本正文 msg.attach(MIMEText(text, 'plain')) # 批量处理附件 for filename in filenames: with open(filename, 'rb') as attachment: # 创建附件对象 part = MIMEBase('application', 'octet-stream') part.set_payload(attachment.read()) # 用base64编码附件内容,确保邮件传输兼容 encoders.encode_base64(part) # 设置附件的头部,让邮件客户端识别为附件 part.add_header( 'Content-Disposition', f'attachment; filename= {os.path.basename(filename)}', ) # 将附件加入邮件容器 msg.attach(part) # 连接Gmail的SMTP服务器,启用TLS加密 server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login(gmail_user, gmail_pwd) # 发送邮件 server.sendmail(gmail_user, to, msg.as_string()) server.quit() print("邮件发送成功!") except Exception as e: print(f"发送失败,错误信息:{str(e)}")
额外提示
现在Gmail已经逐步淘汰“允许低安全性应用”的设置了,这个选项可能随时被移除。更安全的做法是:
- 给你的Gmail账户开启两步验证,然后创建一个应用专用密码来代替原密码使用
- 或者采用OAuth2认证方式,这是Gmail官方推荐的认证方案
内容的提问来源于stack exchange,提问作者Sum
相关产品推荐
相关产品推荐

