python:发送邮件,在 "with" 块内时失败
python: sending a mail, fails when inside a "with" block
我想知道为什么这个代码
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 在 raspberry pi 上)
谢谢
您使用的不是 Python 3.3 或更高版本。在您的 Python 版本中,smtplib.SMTP()
不是上下文管理器,不能在 with
语句中使用。
回溯是直接造成的,因为没有__exit__
method上下文管理器的要求。
来自smptlib.SMTP()
documentation:
Changed in version 3.3: Support for the with
statement was added.
您可以使用 @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)
请注意,它会为您关闭连接。
我想知道为什么这个代码
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 在 raspberry pi 上) 谢谢
您使用的不是 Python 3.3 或更高版本。在您的 Python 版本中,smtplib.SMTP()
不是上下文管理器,不能在 with
语句中使用。
回溯是直接造成的,因为没有__exit__
method上下文管理器的要求。
来自smptlib.SMTP()
documentation:
Changed in version 3.3: Support for the
with
statement was added.
您可以使用 @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)
请注意,它会为您关闭连接。