Python:smtplib 在函数内部时错误地格式化电子邮件,但在函数外部 运行 相同的代码时它正确地格式化它

Python: smtplib incorrectly formats email when inside of a function, but it correctly formats it when the same code is run from outside of a function

出于某种让我无法理解的原因,每当我尝试通过调用函数发送此电子邮件时,电子邮件都缺少主题,缺少 "To:",并且电子邮件的正文偏移了四个空格。但是,当完全相同的代码 运行 直接来自脚本主体时,所有内容的格式都是完美的。

import smtplib

def send_email():
    sender = 'email@address.com'
    receivers = ['email@address.com']

    message_header = """From: Me <email@address.com>
    To: Me <email@address.com>
    Subject: This is the messages's subject

    """

    message_body = 'This is the message\'s body'

    message = message_header + message_body

    try:
        smtpObj = smtplib.SMTP('server_name', 25)
        smtpObj.sendmail(sender, receivers, message)
        print("Successfully sent email")
    except OSError:
        print("Error: unable to send email")

send_email()
def send_email():
    ...
    message_header = """From: Me <email@address.com>
____To: Me <email@address.com>
____Subject: This is the messages's subject

____"""

对比:

message_header = """From: Me <email@address.com>
To: Me <email@address.com>
Subject: This is the messages's subject

"""

请注意,您的函数中有空格,因为它们是缩进的。我已经为您用下划线突出显示了它们。

您可以使用以下方法解决此问题:

def send_email():
    ...
    message_header = """From: Me <email@address.com>
To: Me <email@address.com>
Subject: This is the messages's subject

"""

(这向您展示了如何修复当前代码;我的 向您展示了实现此代码的正确方法。)


message_header 中的每一行,但第一行前面有 4 个空格,包括连接两个字符串后的正文:

>>> repr(message_header)
'"From: Me <email@address.com>\n    To: Me <email@address.com>\n    Subject: This is the messages\'s subject\n\n    "'

(我在 UNIX 环境中对此进行了测试,因此此处显示了 \n。我假设您正在使用带有 DOS 行结尾的文件,该文件已经使用了 SMTP 期望的 \r\n。)

要么自己消灭他们:

def send_email():
    sender = 'email@address.com'
    receivers = ['email@address.com']

    message_header = """From: Me <email@address.com>
To: Me <email@address.com>
Subject: This is the messages's subject

"""

哪个丑,或者用textwrap.dedent:

def send_email():
    sender = 'email@address.com'
    receivers = ['email@address.com']

    message_header = textwrap.dedent(
        """From: Me <email@address.com>
           To: Me <email@address.com>
           Subject: This is the messages's subject

        """)

这从其参数的每一行中删除了相同数量的空格:

dedent(text)
    Remove any common leading whitespace from every line in `text`.

    This can be used to make triple-quoted strings line up with the left
    edge of the display, while still presenting them in the source code
    in indented form.

    Note that tabs and spaces are both treated as whitespace, but they
    are not equal: the lines "  hello" and "    hello" are
    considered to have no common leading whitespace.  (This behaviour is
    new in Python 2.5; older versions of this module incorrectly
    expanded tabs before searching for common leading whitespace.)

更好的是,使用 '\r\n'.join 为您构建字符串。

def send_email():
    sender = 'email@address.com'
    receivers = ['email@address.com']

    headers = [
      'From: Me <email@address.com>',
      'To: Me <email@address.com>',
      "Subject: This is the message's subject"
    ]

    message_body = 'This is the message\'s body'

    message = '\r\n'.join(headers + ['', ''] + [message_body])

除了我的其他回答,您应该使用 email 包来生成消息,而不是尝试手动构建它。

def send_email():
    sender = 'email@address.com'
    receivers = ['email@address.com']

    message_body = 'This is the message\'s body'

    msg = email.MIMEText(message_body)
    msg['Subject'] = "This is the message's subject"
    msg['From'] = 'Me <%s>' % (sender,)
    msg['To'] = ', '.join(receivers)


    try:
        smtpObj = smtplib.SMTP('server_name', 25)
        smtpObj.sendmail(sender, receivers, msg.as_string())
        print("Successfully sent email")
    except OSError:
        print("Error: unable to send email")