Python 无法停止项目源代码中的循环

Python 无法停止项目源代码中的循环,python,string,pandas,loops,smtp,Python,String,Pandas,Loops,Smtp,我正在用Python构建一个自定义电子邮件发送者,使用示例csv数据作为输入。我已经完成了大部分脚本,但是唯一的问题是最后几行代码。如果您运行代码(确保包含您的电子邮件/pwd),您会注意到自定义电子邮件会发送到正确的收件人,但是由于循环,他们会收到多个副本 我在结尾尝试了一个简单的break语句,它只发送了第一封电子邮件,然后就停止了。在google/youtube上也找不到解决方案 import datetime import smtplib import os from email.mim

我正在用Python构建一个自定义电子邮件发送者,使用示例csv数据作为输入。我已经完成了大部分脚本,但是唯一的问题是最后几行代码。如果您运行代码(确保包含您的电子邮件/pwd),您会注意到自定义电子邮件会发送到正确的收件人,但是由于循环,他们会收到多个副本

我在结尾尝试了一个简单的break语句,它只发送了第一封电子邮件,然后就停止了。在google/youtube上也找不到解决方案

import datetime
import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import pandas as pd

host = "smtp.gmail.com"
port = 587
usr = os.environ.get("EMAIL_USER")
pwd = os.environ.get("EMAIL_PASS")
from_email = usr


class MessageUser():
    user_details = []
    messages = []
    email_messages = []
    base_message = "Hi {name}!\n\nThank you for the purchase on {date}. We hope you are exited about using it. Just as a reminder the purchase total was ${total}. Have a great day!"
    def add_user(self, name, amount, email=None):
        name = name[0].upper() + name[1:].lower()
        amount = f"{amount}"
        detail = {
            "name": name,
            "amount": amount,
        }
        today = datetime.date.today()
        date_text = '{today.month}/{today.day}/{today.year}'.format(today=today)
        detail['date'] = date_text
        if email is not None:   # if email != None
            detail["email"] = email
        self.user_details.append(detail)
    def get_details(self):
        return self.user_details
    def make_messages(self):
        if len(self.user_details) > 0:
            for detail in self.get_details():
                name = detail["name"]
                amount = detail["amount"]
                date = detail["date"]
                message = self.base_message
                new_msg = message.format(
                    name=name,
                    date=date,
                    total=amount
                )
                user_email = detail.get("email")
                if user_email:
                    user_data = {
                        "email": user_email,
                        "message": new_msg
                    }
                    self.email_messages.append(user_data)
                else:
                    self.messages.append(new_msg)
            return self.messages
        return []
    def send_email(self):
        self.make_messages()
        if len(self.email_messages) > 0:
            for detail in self.email_messages:
                user_email = detail['email']
                user_message = detail['message']
                try:
                    email_conn = smtplib.SMTP(host, port)
                    email_conn.ehlo()
                    email_conn.starttls()
                    email_conn.login(usr, pwd)
                    the_msg = MIMEMultipart("alternative")
                    the_msg["Subject"] = "Billing Update"
                    the_msg["From"] = from_email
                    the_msg["To"] = user_email
                    part_1 = MIMEText(user_message, "plain")
                    the_msg.attach(part_1)
                    email_conn.sendmail(from_email, [user_email], the_msg.as_string())
                except smtplib.SMTPException:
                    print("Error sending message.")
            return True
        return False

df = pd.read_csv('test_data.csv')

Name = df.Name
Amount = df.Price
Email = df.Email

for name, amount, email in zip(Name, Amount, Email):
    obj = MessageUser()
    obj.add_user(f'{name}', f'{amount}', email=f'{email}')
    obj.get_details()
    obj.send_email()

# Works but need loop break suggestion.
预期:向所有收件人发送自定义电子邮件一次。
实际:由于循环结束,会多次收到自定义电子邮件。

最可能的问题是您的
.csv
文件有重复的用户/电子邮件。您也许应该更好地研究代码的结构,以便能够更轻松地调试代码

本质上,您希望确保解耦功能,以便可以单独测试每个功能,这样就不会出现类似的场景。以以下为例:

将熊猫作为pd导入
类用户:
定义初始化(自我、电子邮件、姓名、价格):
self.email=电子邮件
self.name=名称
self.price=价格
def发送电子邮件给用户(自我):
“”“向用户发送电子邮件。”“”
发送电子邮件。发送电子邮件(自我)
定义(自身、其他):
“”“用标准==表示法检查用户是否相等。”“”
如果(
self.email==其他.email
和self.name==self.name
和self.price==self.price
):
返回真值
其他:
返回错误
类别发送电子邮件:
@静力学方法
def create_消息(用户):
“”“创建要发送的邮件模板。”“”
返回{user.price}的f{user.name}:{user.email}
@静力学方法
def发送电子邮件(用户):
“”“向通过的用户发送电子邮件。”“”
name=user.name
email=user.email
价格=用户价格
message=sendmail.create_message(用户)
打印(f“将消息{message}发送给用户。”)
数据={
“名称”:[“名称1”、“名称2”、“名称1”、“名称3”],
“电子邮件”:[“电子邮件1”、“电子邮件2”、“电子邮件1”、“电子邮件3”],
“价格”:[“1美元”、“2美元”、“1美元”、“3美元],
}
df=pd.DataFrame(数据)
用户=[]
对于zip中的名称、电子邮件、价格(df.name、df.email、df.price):
用户=用户(姓名、电子邮件、价格)
#当我们使用“用户不在用户中”时,我们在这里使用_ueq__;方法。
如果用户不在用户中:
附加(用户)
其他:
印刷品(
f“似乎名为{name}的用户已经在用户列表中。”
)
对于用户中的用户:
user.send_email_to_user()
上述产出:

It seems the user with the name name1 is already in the list of users.
Sending the message <b>email1: name1 for $1</b> to the user.
Sending the message <b>email2: name2 for $2</b> to the user.
Sending the message <b>email3: name3 for $3</b> to the user.
名为name1的用户似乎已经在用户列表中。
以$1的价格向用户发送邮件email1:name1。
以$2的价格向用户发送邮件email2:name2。
以3美元的价格向用户发送邮件email3:name3。

注意上面的代码是如何解耦我们的功能的。这样,我们可以更容易地测试是否可以发送和模板化电子邮件(通过
sendmail
对象),当然,最终可以通过
users
类将电子邮件发送给用户

最可能的问题是您的
.csv
文件有重复的用户/电子邮件。您也许应该更好地研究代码的结构,以便能够更轻松地调试代码

本质上,您希望确保解耦功能,以便可以单独测试每个功能,这样就不会出现类似的场景。以以下为例:

将熊猫作为pd导入
类用户:
定义初始化(自我、电子邮件、姓名、价格):
self.email=电子邮件
self.name=名称
self.price=价格
def发送电子邮件给用户(自我):
“”“向用户发送电子邮件。”“”
发送电子邮件。发送电子邮件(自我)
定义(自身、其他):
“”“用标准==表示法检查用户是否相等。”“”
如果(
self.email==其他.email
和self.name==self.name
和self.price==self.price
):
返回真值
其他:
返回错误
类别发送电子邮件:
@静力学方法
def create_消息(用户):
“”“创建要发送的邮件模板。”“”
返回{user.price}的f{user.name}:{user.email}
@静力学方法
def发送电子邮件(用户):
“”“向通过的用户发送电子邮件。”“”
name=user.name
email=user.email
价格=用户价格
message=sendmail.create_message(用户)
打印(f“将消息{message}发送给用户。”)
数据={
“名称”:[“名称1”、“名称2”、“名称1”、“名称3”],
“电子邮件”:[“电子邮件1”、“电子邮件2”、“电子邮件1”、“电子邮件3”],
“价格”:[“1美元”、“2美元”、“1美元”、“3美元],
}
df=pd.DataFrame(数据)
用户=[]
对于zip中的名称、电子邮件、价格(df.name、df.email、df.price):
用户=用户(姓名、电子邮件、价格)
#当我们使用“用户不在用户中”时,我们在这里使用_ueq__;方法。
如果用户不在用户中:
附加(用户)
其他:
印刷品(
f“似乎名为{name}的用户已经在用户列表中。”
)
对于用户中的用户:
user.send_email_to_user()
上述产出:

It seems the user with the name name1 is already in the list of users.
Sending the message <b>email1: name1 for $1</b> to the user.
Sending the message <b>email2: name2 for $2</b> to the user.
Sending the message <b>email3: name3 for $3</b> to the user.
名为name1的用户似乎已经在用户列表中。
以$1的价格向用户发送邮件email1:name1。
以$2的价格向用户发送邮件email2:name2。
以3美元的价格向用户发送邮件email3:name3。

注意上面的代码是如何解耦我们的功能的。这样,我们可以更容易地测试是否可以发送和模板化电子邮件(通过
sendmail
对象),当然,最终可以通过
users
类将电子邮件发送给用户

我不认为这是一个循环中的问题。您确定
.csv
文件中的所有电子邮件都是唯一的吗?你现在过得更好