使用Python发送CSV邮件附件时遇'list'对象无encode属性错误求助
解决Python发送带CSV附件邮件时的'list' object has no attribute 'encode'错误
错误原因分析
- 收件人格式不兼容:
read_managers_email()返回的是邮箱列表,但EmailMessage的To字段需要传入逗号分隔的字符串,直接赋值列表会触发编码错误。 - 附件处理方式错误:
- 读取CSV文件用了文本模式
'r',但二进制附件需要用二进制模式'rb'读取; - 混用
MIMEApplication和EmailMessage的attach方法,容易出现格式兼容问题,EmailMessage推荐用自身的add_attachment方法添加附件。
- 读取CSV文件用了文本模式
修正后的代码
import os import smtplib from email.message import EmailMessage def send_csv(): csv_file = check_consumable_status() if csv_file: mail_server = log_in_mail_server() recipients = read_managers_email() notification_email = create_notification_email(csv_file) if send_email(mail_server, notification_email, recipients): print("Mail sent") else: print("Unable to read subscription status") return def create_notification_email(csv): notification_email = EmailMessage() notification_email['Subject'] = "consumable notification" notification_email['From'] = os.environ["EMAIL_USER"] # 用二进制模式读取文件,适配附件要求 with open('consumable_notification.csv', 'rb') as file: # 使用EmailMessage原生的add_attachment方法,更简洁兼容 notification_email.add_attachment( file.read(), maintype='application', subtype='octet-stream', filename='consumable_notification.csv' ) return notification_email def send_email(server, email, to_address): try: # 将邮箱列表转为逗号分隔的字符串,适配EmailMessage的To字段要求 email['To'] = ', '.join(to_address) server.send_message(email) return True except Exception as e: print("Failed to send email") print(e) return False def log_in_mail_server(): SERVER = os.environ["EMAIL_SERVER"] PORT = int(os.environ["EMAIL_PORT"]) # 转换为整数,避免端口类型错误 try: server = smtplib.SMTP(SERVER, PORT) server.ehlo() server.starttls() server.ehlo() user = os.environ["EMAIL_USER"] password = os.environ["EMAIL_PASSWORD"] server.login(user, password) print("Successfully log in to server") return server except Exception as e: print("Failed to log in to server") print(e) return False
关键修改点说明
- 收件人处理:用
', '.join(to_address)将邮箱列表转为符合邮件标准的字符串格式; - 附件读取:把文件打开模式从
'r'改为'rb',确保读取二进制数据; - 附件添加:改用
EmailMessage.add_attachment()方法,参数更清晰,避免MIME类和EmailMessage的兼容问题; - 端口转换:添加
int(os.environ["EMAIL_PORT"]),确保端口是整数类型,避免连接错误。
内容的提问来源于stack exchange,提问作者tjarne
相关产品推荐
相关产品推荐

