Python,结合 if 和 for 循环

Python, combining if and for loops

你好,我有这个程序,它基本上进入收件箱,然后查看最新的电子邮件。扫描它,如果它有一个 link 它会给你一个通知,或者如果它有一个附件它会给出一个通知。尽管我尝试将两个通知合二为一,但一切正常。所以它更好一点,而不是先显示一个通知,然后再显示另一个。如果电子邮件同时包含 link 和附件。 如果电子邮件同时包含这两个通知,我更希望它只是一个通知,如果它们仅包含 link 或附件,则我希望它是单独的通知。我试图将其拆分为 if 和 elif 循环。

如果我在 if 语句的循环中执行 'and',我可以获得针对两者出现的通知 - 例如

if any(word in html_text for word in word) and file_name == None:
    fboth()

fboth()(这个函数会告诉你同时存在 link 和附件,就像 flink() 和 fattach())

尽管当我将其他选项作为 elif: 语句时,一个用于 link 本身,一个用于附件本身。即使它发现第一个语句为 True 并且它警告电子邮件同时具有 link 和附件,这些仍然会发生。有办法阻止这个吗?我开始认为这是另一个 if 语句?但我有几次失败的尝试,可能没有完全理解它。我的理论是否正确,我仍然使用 for 循环来解决它?

代码如下:

import imaplib
import email
import Tkinter as tk
import time

word = ["href=", "href", "<a href="] #list of strings to search for in email body

#connection to the email server
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('xxxx', 'xxxx')
mail.list()


latest_email_uid = ''

#Finding a link popup
def flink():
    flink = tk.Tk()
    flink.title("Found Link")

    tk.Label(flink, text="Email has link in body\n" + "From: " + msg['From'] + "\n" + "Subject: " + msg['Subject'] + "\n" + "Date: " + msg['Date'], fg='yellow', bg='black').pack()
    flink.after(5000, lambda: flink.destroy())     # time in ms
    flink.mainloop()

#Finding an attachment popup
def fattach():
    fattach = tk.Tk()
    fattach.title("Found Attachment")

    tk.Label(fattach, text= " Latest Email has attachment\n" + "Filename: " + file_name + "\n" + "Fron: " + msg['From'] + "\n" + "Subject: " + msg['Subject'] + "\n" + "Date: " + msg['Date'], fg='yellow', bg='black').pack()
    fattach.after(5000, lambda: fattach.destroy())     # time in ms
    fattach.mainloop()

while True:
    mail.select("Inbox", readonly=True) # connect to inbox.
    result, data = mail.uid('search', None, "ALL") # search and return uids instead
    ids = data[0] # data is a list.
    id_list = ids.split() # ids is a space separated string

    if data[0].split()[-1] == latest_email_uid:
        time.sleep(120) # value here once per minute is already considered fairly aggressive by many IMAP server admins. Depending on your application and expected

    else:
        latest_email_uid = data[0].split()[-1]
        result, data = mail.uid('fetch', latest_email_uid, '(RFC822)') # fetch the email headers and body (RFC822) for the given ID7
        raw_email = data[0][1]

        # "---------------------------------------------------------"
        # "Are there links in the email?"
        # "---------------------------------------------------------"

        msg = email.message_from_string(raw_email)
        for part in msg.walk():
            # each part is a either non-multipart, or another multipart message
            # that contains further parts... Message is organized like a tree
            if part.get_content_type() == 'text/html':
                html_text = part.get_payload()

                if any(word in html_text for word in word):
                    flink()
                else:
                    pass

        # "---------------------------------------------------------"
        # "Are there attachments?"
        # "---------------------------------------------------------"

        for part in msg.walk():
            attach = part.get_content_type()
            file_name = part.get_filename()

            if file_name == None:
                pass
            else:
                fattach()

        mail.close()

        time.sleep(120)

编辑:好的,我已经走到这一步了,我可以循环查找电子邮件正文(第一个 elif)中只有 link 的消息,但其他任何方法都不起作用。当发送一个附件时,应该使我的 file_name != 现在变成 None,是吗?

        msg = email.message_from_string(raw_email)
        for part in msg.walk():
            attach = part.get_content_type()
            file_name = part.get_filename()
            # each part is a either non-multipart, or another multipart message
            # that contains further parts... Message is organized like a tree
            if part.get_content_type() == 'text/html':
                html_text = part.get_payload()
                text = any(word in html_text for word in word)

                if text == True and file_name != None:
                    print "file name and attachment"
                elif text == True and file_name == None:
                    print "Just link in text"
                elif text == False and file_name != None:
                    print "just an attachment"

你不必要地做了两次 walk。只需在同一个循环中调用这两个函数即可。

    maybe = False
    msg = email.message_from_string(raw_email)
    for part in msg.walk():
        if part.get_content_type() == 'text/html':
            html_text = part.get_payload()

            if any(word in html_text for word in word):
                maybe = True
        else:
            attach = part.get_content_type()
            file_name = part.get_filename()
            if file_name == None:
                pass
            else:
                maybe = True

    mail.close()
    if maybe:
        # display message

如果您希望邮件更详细地反映是否有 link 或附件或两者兼而有之,您可以将 maybe 标志变量从简单的布尔值更改为例如传递给消息显示函数的 set 以指示确切填充消息对话框的字符串。