How to fix 'AttributeError: partially initialized module 'SendEmail' has no attribute 'send_email' (most likely due to a circular import)'
How to fix 'AttributeError: partially initialized module 'SendEmail' has no attribute 'send_email' (most likely due to a circular import)'
所以我正在使用 Tkinter 创建一个 Gmail 发件人应用程序,我有一个名为 send_email 的函数,它位于 SendEmail.py 中。但是每次我 运行 代码都会给我这个错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1885, in __call__
return self.func(*args)
File "C:\Users\User\Desktop\Coding\Python\GmailSenderApp\Main.py", line 114, in <lambda>
send = tk.Button(mainframe, text="Send Email", font=('Calibri', 15), command=lambda: SendEmail.send_email())
AttributeError: partially initialized module 'SendEmail' has no attribute 'send_email' (most likely due to a circular import)
在Main.py中我正在导入SendMail.py因为它包含发送电子邮件的功能
这是 Main.py 代码:
import tkinter as tk
import time
from tkinter import filedialog
import SendEmail
# Main Screen
root = tk.Tk()
root.resizable(False, False)
root.title('Mail Sender')
# Icon
icon = tk.PhotoImage(file='icon.png')
root.iconphoto(False, icon)
# Canvas
canvas = tk.Canvas(root, height=600, width=700)
canvas.pack()
# title
titleFrame = tk.Frame(root)
titleFrame.place(relx=0.5, rely=0.025, relwidth=0.75, relheight=0.1, anchor='n')
title = tk.Label(titleFrame, text="Mail Sender", font=('Calibri', 20))
title.pack()
# Main frame
mainframe = tk.Frame(root, bg='#80c1ff', bd=10)
mainframe.place(relx=0.5, rely=0.15, relwidth=1, relheight=0.85, anchor='n')
# Email
email = tk.Label(mainframe, text="Enter Email:", font=('Calibri', 15))
email.place(y=2.5)
email_str = tk.StringVar()
emailEntry = tk.Entry(mainframe, textvariable=email_str, font=('Calibri', 15))
emailEntry.place(y=35, width=300)
# password
password = tk.Label(mainframe, text="Enter Password:", font=('Calibri', 15))
password.place(y=80)
password_str = tk.StringVar()
passwordEntry = tk.Entry(mainframe, textvariable=password_str, show="\u2022", font=('Calibri', 15))
passwordEntry.place(y=115, width=300)
# receiver
receiver = tk.Label(mainframe, text="Enter Receiver Email:", font=('Calibri', 15))
receiver.place(y=150)
receiver_str = tk.StringVar()
receiverEntry = tk.Entry(mainframe, textvariable=receiver_str, font=('Calibri', 15))
receiverEntry.place(y=185, width=300)
# subject
subject = tk.Label(mainframe, text="Enter Subject:", font=('Calibri', 15))
subject.place(y=220)
subject_str = tk.StringVar()
subjectEntry = tk.Entry(mainframe, textvariable=subject_str, font=('Calibri', 15))
subjectEntry.place(y=255, width=300)
# body
body = tk.Label(mainframe, text="Enter Body:", font=('Calibri', 15))
body.place(x=500, y=2.5)
body_str = tk.StringVar()
bodyEntry = tk.Text(mainframe)
bodyEntry.place(x=380, y=35, width=300)
# notification
notif = tk.Label(mainframe, bg='#80c1ff', font=('Calibri', 15))
notif.place(x=250, y=450)
# attachments array
attachments = []
# add attacments function
def add_attachments():
filename = filedialog.askopenfilename(initialdir='C:/', title="Select a file to attach to the email")
attachments.append(filename)
notif.config(text="Attached " + str(len(attachments)) + " file", fg="green")
root.update()
time.sleep(2.5)
notif.config(text="")
def reset_entries():
emailEntry.delete(0, 'end')
passwordEntry.delete(0, 'end')
receiverEntry.delete(0, 'end')
subjectEntry.delete(0, 'end')
bodyEntry.delete("1.0", "end-1c")
notif.config(text="Entries were reset", fg="green")
root.update()
time.sleep(2.5)
notif.config(text="")
# send button
send = tk.Button(mainframe, text="Send Email", font=('Calibri', 15), command=lambda: SendEmail.send_email())
send.place(y=310, width=150)
# reset button
reset = tk.Button(mainframe, text="Reset", font=('Calibri', 15), command=lambda: ResetEntries.reset_entries())
reset.place(x=220, y=310, width=150)
# attachments button
attachment = tk.Button(mainframe, text="Add Attachments", font=('Calibri', 15), command=lambda: add_attachments())
attachment.place(x=90, y=365, width=200)
# Main loop
root.mainloop()
在 SendMail.py 中我导入了 Main.py 因为我正在使用该文件中的变量
这是发送Main.py代码:
import Main
import smtplib
import time
from email.message import EmailMessage
# send function
def send_email():
try:
msg = EmailMessage()
emailText = Main.email_str.get()
passwordText = Main.password_str.get()
receiverText = Main.receiver_str.get()
subjectText = Main.subject_str.get()
bodyText = Main.bodyEntry.get("1.0", "end-1c")
msg['Subject'] = subjectText
msg['From'] = emailText
msg['To'] = receiverText
msg.set_content(bodyText)
if emailText == "" or passwordText == "" or receiverText == "" or subjectText == "" or bodyText == "":
Main.notif.config(text="All fields are required!", fg="red")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
return
else:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(emailText, passwordText)
server.send_message(msg)
Main.emailEntry.delete(0, 'end')
Main.passwordEntry.delete(0, 'end')
Main.receiverEntry.delete(0, 'end')
Main.subjectEntry.delete(0, 'end')
Main.bodyEntry.delete("1.0", "end-1c")
Main.notif.config(text="Email Sent!", fg="green")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
except:
Main.notif.config(text="There was a error please try again", fg="red")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
所以有谁知道如何解决这个问题我被卡住了我想不通。提前致谢
您正在尝试从导入文件的文件中导入文件。这导致 circular import。相反,您应该将两个文件中需要的代码放在第三个文件中,然后将其导入两个文件中。
请参阅下面的示例
variables.py
foo = "bar"
main.py
import variables
import second
print(foo)
second.py
import variables
print(foo)
对于您的示例,您需要移动 notif
、root
、emailEntry
、passwordEntry
、receiverEntry
、subjectEntry
和 bodyEntry
到另一个文件,连同他们依赖的东西。
所以我正在使用 Tkinter 创建一个 Gmail 发件人应用程序,我有一个名为 send_email 的函数,它位于 SendEmail.py 中。但是每次我 运行 代码都会给我这个错误:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1885, in __call__
return self.func(*args)
File "C:\Users\User\Desktop\Coding\Python\GmailSenderApp\Main.py", line 114, in <lambda>
send = tk.Button(mainframe, text="Send Email", font=('Calibri', 15), command=lambda: SendEmail.send_email())
AttributeError: partially initialized module 'SendEmail' has no attribute 'send_email' (most likely due to a circular import)
在Main.py中我正在导入SendMail.py因为它包含发送电子邮件的功能 这是 Main.py 代码:
import tkinter as tk
import time
from tkinter import filedialog
import SendEmail
# Main Screen
root = tk.Tk()
root.resizable(False, False)
root.title('Mail Sender')
# Icon
icon = tk.PhotoImage(file='icon.png')
root.iconphoto(False, icon)
# Canvas
canvas = tk.Canvas(root, height=600, width=700)
canvas.pack()
# title
titleFrame = tk.Frame(root)
titleFrame.place(relx=0.5, rely=0.025, relwidth=0.75, relheight=0.1, anchor='n')
title = tk.Label(titleFrame, text="Mail Sender", font=('Calibri', 20))
title.pack()
# Main frame
mainframe = tk.Frame(root, bg='#80c1ff', bd=10)
mainframe.place(relx=0.5, rely=0.15, relwidth=1, relheight=0.85, anchor='n')
# Email
email = tk.Label(mainframe, text="Enter Email:", font=('Calibri', 15))
email.place(y=2.5)
email_str = tk.StringVar()
emailEntry = tk.Entry(mainframe, textvariable=email_str, font=('Calibri', 15))
emailEntry.place(y=35, width=300)
# password
password = tk.Label(mainframe, text="Enter Password:", font=('Calibri', 15))
password.place(y=80)
password_str = tk.StringVar()
passwordEntry = tk.Entry(mainframe, textvariable=password_str, show="\u2022", font=('Calibri', 15))
passwordEntry.place(y=115, width=300)
# receiver
receiver = tk.Label(mainframe, text="Enter Receiver Email:", font=('Calibri', 15))
receiver.place(y=150)
receiver_str = tk.StringVar()
receiverEntry = tk.Entry(mainframe, textvariable=receiver_str, font=('Calibri', 15))
receiverEntry.place(y=185, width=300)
# subject
subject = tk.Label(mainframe, text="Enter Subject:", font=('Calibri', 15))
subject.place(y=220)
subject_str = tk.StringVar()
subjectEntry = tk.Entry(mainframe, textvariable=subject_str, font=('Calibri', 15))
subjectEntry.place(y=255, width=300)
# body
body = tk.Label(mainframe, text="Enter Body:", font=('Calibri', 15))
body.place(x=500, y=2.5)
body_str = tk.StringVar()
bodyEntry = tk.Text(mainframe)
bodyEntry.place(x=380, y=35, width=300)
# notification
notif = tk.Label(mainframe, bg='#80c1ff', font=('Calibri', 15))
notif.place(x=250, y=450)
# attachments array
attachments = []
# add attacments function
def add_attachments():
filename = filedialog.askopenfilename(initialdir='C:/', title="Select a file to attach to the email")
attachments.append(filename)
notif.config(text="Attached " + str(len(attachments)) + " file", fg="green")
root.update()
time.sleep(2.5)
notif.config(text="")
def reset_entries():
emailEntry.delete(0, 'end')
passwordEntry.delete(0, 'end')
receiverEntry.delete(0, 'end')
subjectEntry.delete(0, 'end')
bodyEntry.delete("1.0", "end-1c")
notif.config(text="Entries were reset", fg="green")
root.update()
time.sleep(2.5)
notif.config(text="")
# send button
send = tk.Button(mainframe, text="Send Email", font=('Calibri', 15), command=lambda: SendEmail.send_email())
send.place(y=310, width=150)
# reset button
reset = tk.Button(mainframe, text="Reset", font=('Calibri', 15), command=lambda: ResetEntries.reset_entries())
reset.place(x=220, y=310, width=150)
# attachments button
attachment = tk.Button(mainframe, text="Add Attachments", font=('Calibri', 15), command=lambda: add_attachments())
attachment.place(x=90, y=365, width=200)
# Main loop
root.mainloop()
在 SendMail.py 中我导入了 Main.py 因为我正在使用该文件中的变量 这是发送Main.py代码:
import Main
import smtplib
import time
from email.message import EmailMessage
# send function
def send_email():
try:
msg = EmailMessage()
emailText = Main.email_str.get()
passwordText = Main.password_str.get()
receiverText = Main.receiver_str.get()
subjectText = Main.subject_str.get()
bodyText = Main.bodyEntry.get("1.0", "end-1c")
msg['Subject'] = subjectText
msg['From'] = emailText
msg['To'] = receiverText
msg.set_content(bodyText)
if emailText == "" or passwordText == "" or receiverText == "" or subjectText == "" or bodyText == "":
Main.notif.config(text="All fields are required!", fg="red")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
return
else:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(emailText, passwordText)
server.send_message(msg)
Main.emailEntry.delete(0, 'end')
Main.passwordEntry.delete(0, 'end')
Main.receiverEntry.delete(0, 'end')
Main.subjectEntry.delete(0, 'end')
Main.bodyEntry.delete("1.0", "end-1c")
Main.notif.config(text="Email Sent!", fg="green")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
except:
Main.notif.config(text="There was a error please try again", fg="red")
Main.root.update()
time.sleep(2.5)
Main.notif.config(text="")
所以有谁知道如何解决这个问题我被卡住了我想不通。提前致谢
您正在尝试从导入文件的文件中导入文件。这导致 circular import。相反,您应该将两个文件中需要的代码放在第三个文件中,然后将其导入两个文件中。
请参阅下面的示例
variables.py
foo = "bar"
main.py
import variables
import second
print(foo)
second.py
import variables
print(foo)
对于您的示例,您需要移动 notif
、root
、emailEntry
、passwordEntry
、receiverEntry
、subjectEntry
和 bodyEntry
到另一个文件,连同他们依赖的东西。