pythonemail-attachmentsfile-in-use

How to close the file after sending emails with an attachment?


I have a loop which sends email with an attachment to the people in emailing list. The problem is, when it comes to the last person in the list, the file I am attaching on email still stays as in use in Windows.

for index, row in f.iterrows():
    print (row["ManagerEmail"]+row["filename"])
    msg = MIMEMultipart()
    msg['From'] = fromaddr
    msg['Subject'] = row["filename"] + f" Sales Letter"
    msg.attach(MIMEText(body, 'plain'))
    filename = row["filename"]
    toaddr = row["ManagerEmail"]
    attachment = open(row["filepath"], "rb")
    part = MIMEBase('application', 'octet-stream')
    part.set_payload((attachment).read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
    msg.attach(part)
    text = msg.as_string()
    server.sendmail(fromaddr, toaddr, text)

Somehow I need to put a parameter at the end to close the file but I do not know how to do that.


Solution

  • Just like you open a file with open() you need to close it with close() As in attachment.close(). Or, even better, use context manager:

    with open(row["filepath"], "rb") as attachment:
       # Code that uses attachment file goes here
    # Code that no longer uses that file goes here
    

    Context managers guarantee that file will be closed outside of the with block.