python3 MIME 和文件对象不工作

python3 mime and file object not working

我正在尝试为 python3 使用以下邮件功能,它会抛出错误 NameError: name 'file' is not defined,它非常适合 python2。

我知道 file() is not supported in Python 3 什么可以替代 file

#!/usr/bin/env python3
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import os
############ File comparison & sendmail part starts here ########
def ps_Mail():
    filename = "/tmp/ps_msg"
    f = file(filename)
    if os.path.exists(filename) and os.path.getsize(filename) > 0:
        mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
        msg = MIMEMultipart('alternative')
        msg['To'] = "sam@seemac.com"
        msg['Subject'] = "Uhh!! Unsafe process seen"
        msg['From'] = "psCheck@seemac.com"
        msg1 = MIMEText(filename.read(),  'text')
        msg.attach(msg1)
        mailp.communicate(msg.as_string())
ps_Mail()

我已经编辑了你的代码,这应该可以,请试试这个...

有两个关键点需要更改 universal_newlines=True 并使用 open() 而不是 file()

#!/usr/bin/env python3
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import os
############ File comparison & sendmail part starts here ########
def ps_Mail():
    filename = "/tmp/ps_msg"
    f = open(filename)
    if os.path.exists(filename) and os.path.getsize(filename) > 0:
        mailp = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE, universal_newlines=True)
        msg = MIMEMultipart('alternative')
        msg['To'] = "sam@seemac.com"
        msg['Subject'] = "Uhh!! Unsafe process seen"
        msg['From'] = "psCheck@seemac.com"
        msg1 = MIMEText(filename.read(),  'text')
        msg.attach(msg1)
        mailp.communicate(msg.as_string())
ps_Mail()

更多详情....

使用 universal_newlines=True(bufsize=1)和使用 Popen

默认参数有什么区别

默认值是:universal_newlines=False(意思是 input/output 被接受为字节,而不是 Unicode 字符串加上通用换行模式处理(因此参数名称虽然 text_mode 在这里可能是一个更好的名字)被禁用——你得到的是二进制数据(除非 Windows 上的 POSIX 层把它搞砸了)和 bufsize=-1 (意味着流被完全缓冲 - - 使用默认缓冲区大小。

universal_newlines=True 使用 locale.getpreferredencoding(False) 字符编码来解码字节(这可能与代码中使用的 ascii 编码不同)。

If universal_newlines=False then for line in Robocopy.stdout: 遍历 b'\n' 分隔的行。如果进程使用非 ascii 编码,例如 UTF-16 作为其输出,那么即使 os.linesep == '\n' 在您的系统上;你可能会得到错误的结果。如果要使用文本行,请使用文本模式:传递 universal_newlines=True 或显式使用 io.TextIOWrapper(process.stdout)。

第二个版本确实包含 universal_newlines,因此我指定了一个 bufsize。

一般情况下,如果使用universal_newlines,则不必指定bufsize(可以但不是必需的)。而且您不需要在您的情况下指定 bufsize。 bufsize=1 启用行缓冲模式(如果您要写入 process.stdin,输入缓冲区会在换行时自动刷新)否则它等同于默认的 bufsize=-1.