2015-01-10 28 views
1

當我想知道失敗爲何這段代碼蟒蛇:發送郵件,裏面是「與」塊

test = smtplib.SMTP('smtp.gmail.com', 587) 
test.ehlo() 
test.starttls() 
test.ehlo() 
test.login('address','passw') 
test.sendmail(sender, recipients, composed) 
test.close() 

作品,但是當這樣寫的

with smtplib.SMTP('smtp.gmail.com', 587) as s: 
    s.ehlo() 
    s.starttls() 
    s.ehlo() 
    s.login('address','passw') 
    s.sendmail(sender, recipients, composed) 
    s.close() 

它失敗的消息

Unable to send the email. Error: <class 'AttributeError'> 
Traceback (most recent call last): 
    File "py_script.py", line 100, in <module> 
    with smtplib.SMTP('smtp.gmail.com', 587) as s: 
AttributeError: __exit__ 

這是爲什麼發生? (在樹莓派上的python3) Thx

回答

3

你沒有使用Python 3.3或更高版本。在您的Python版本中,smtplib.SMTP()不是上下文管理器,不能在with語句中使用。

回溯是由於沒有__exit__ method,這是對上下文管理器的要求而直接導致的。

smptlib.SMTP() documentation

改變在3.3版本:添加了對with發言表示支持。

您可以@contextlib.contextmanager包裹在上下文管理對象:

from contextlib import contextmanager 
from smtplib import SMTPResponseException, SMTPServerDisconnected 

@contextmanager 
def quitting_smtp_cm(smtp): 
    try: 
     yield smtp 
    finally: 
     try: 
      code, message = smtp.docmd("QUIT") 
      if code != 221: 
       raise SMTPResponseException(code, message) 
     except SMTPServerDisconnected: 
      pass 
     finally: 
      smtp.close() 

中採用相同的退出行爲是在Python 3.3加入。像這樣使用它:

with quitting_smtp_cm(smtplib.SMTP('smtp.gmail.com', 587)) as s: 
    s.ehlo() 
    s.starttls() 
    s.ehlo() 
    s.login('address','passw') 
    s.sendmail(sender, recipients, composed) 

請注意,它會爲您關閉連接。

+0

然後這是錯誤的(?)http://robertwdempsey.com/python3-email-with-attachments-using-gmail/ – Gerard

+0

但在python3?我在版本3中嘗試它編輯:好的,我有python 3.2.3,謝謝:) – Gerard

+0

@Gerard:文檔說明它是在Python 3.3中作爲上下文管理器。 –