0

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.

martineau
  • 119,623
  • 25
  • 170
  • 301
segababa
  • 146
  • 1
  • 8
  • Does this answer your question? [Does reading an entire file leave the file handle open?](https://stackoverflow.com/questions/7409780/does-reading-an-entire-file-leave-the-file-handle-open) – mkrieger1 May 05 '22 at 11:57

1 Answers1

5

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.

matszwecja
  • 6,357
  • 2
  • 10
  • 17