我正在尝试从另一个 python 运行一个 python 文件,但是当涉及到调用另一个 python 文件中的方法时,它只会重新运行当前的 python 文件。
我尝试了这段代码。我将导入放入 log_user_in 方法中,因为如果我将其导入到文件顶部,则会出现循环导入错误。 这是我的代码片段
from tkinter import *
import mysql.connector
import customtkinter
import math
from datetime import datetime
class LoginOrReg:
def __init__(self, db, cursor, login_username, data):
self.db = mysql.connector.connect(host = '***', user = '***', password= '***', database="***")
self.cursor = self.db.cursor()
self.login_username = login_username
self.data = data
#provides the login screen where the user is asked for an existing username and password
def login(self):
self.login_window = customtkinter.CTk()
self.login_window.geometry('400x400')
self.login_username_entry = customtkinter.CTkEntry(self.login_window, placeholder_text ='Enter Your Username')
self.login_username_entry.pack(pady=30)
self.login_username = self.login_username_entry.get()
self.login_password_entry = customtkinter.CTkEntry(self.login_window, placeholder_text ='Enter Your Password')
self.login_password_entry.pack(pady=30)
self.login_password = self.login_password_entry.get()
self.log_user_in_button = customtkinter.CTkButton(self.login_window, text = 'Login', command = self.log_user_in).pack(pady=30)
self.reg_button = customtkinter.CTkButton(self.login_window, text = 'Register New User', command = self.reg_user).pack(pady=20)
self.login_window.mainloop()
#Logs the user in
def log_user_in(self):
import HabitTracker as HT
self.habit = HT.HabitTracker(main_window=' ', sorting_options= ' ', sort= ' ', login= ' ')
self.cursor.execute('SELECT username AND password, COUNT(*) FROM users WHERE username=%s AND password=%s GROUP BY username',(self.login_username_entry.get(), self.login_password_entry.get()))
self.cursor.fetchall()
self.row_count = self.cursor.rowcount
if self.row_count == 1:
self.cursor.execute('SELECT userID FROM users WHERE username=%s AND password=%s',(self.login_username_entry.get(), self.login_password_entry.get()))
self.data = self.cursor.fetchone()
print(self.data)
self.user_id = self.data[0]
self.habit.main_menu()
else:
self.my_label = customtkinter.CTkLabel(self.login_window, text = "User Not Found. Please Try Again.", font=('Helvetica', 10)).pack(pady=10)
login_reg = LoginOrReg(db = " ", cursor=" ", login_username= ' ', data = ' ')
login_reg.login_or_reg(root=" ")
这是我想运行的第一个文件。它运行良好,直到我输入有效的用户名和密码,然后当我单击登录时,它会重新运行该文件。我认为它根本不运行 Log_user_in 方法,因为“print(self.data)”代码行没有出现在终端中。
下面是我要运行的第二个文件(即 HabitTracker)的片段。|| |此 HabitTracker 类位于名为 HabitTracker 的文件中。
from tkinter import *
import mysql.connector
import customtkinter
import math
from datetime import datetime
class HabitTracker:
def __init__(self, main_window, sorting_options, sort, login) -> None:
self.main_window = main_window
self.db = mysql.connector.connect(host = '***', user = '***', password= '***', database="***")
self.cursor = self.db.cursor()
self.sorting_options = sorting_options
self.sort = sort
self.login = login
def main_menu(self):
import LoginOrReg as LR
self.login = LR.LoginOrReg(db=' ', cursor= ' ', login_username=' ', data= ' ')
self.date = datetime.today()
self.main_window = customtkinter.CTk()
self.main_window.geometry('1080x720')
self.sorting_options = ['Daily', 'Weekly', 'Monthly', 'Highest Streak',]
self.mylabel = customtkinter.CTkLabel(self.main_window, text='Welcome {}'.format(self.login.login_username), font=('Arial', 40)).pack(pady=5)
self.sort = customtkinter.CTkComboBox(self.main_window, values= self.sorting_options, command= sort_by.sort_by)
self.sort.set('Sort By')
self.sort.pack(pady=10)
self.create_new_habit_button = customtkinter.CTkButton(self.main_window, text='Create New Habit', command=create_habit.create_habit, fg_color='green').pack(pady=20)
self.cursor.execute('SELECT habit_name FROM habit WHERE user_id=%s GROUP BY habit_name', (self.login.data))
self.habits = self.cursor.fetchall()
self.j = 0
for j in self.habits:
self.habit_button = customtkinter.CTkButton(self.main_window, text=self.habits[self.j], command=lambda k = self.habits[self.j]: edit_habit.edit_habit(k))
self.habit_button.pack(pady=10)
self.j = self.j + 1
self.main_window.mainloop()
This HabitTracker class is in the file called HabitTracker.
问题在于试图在应用程序中以一种会导致问题的非传统方式导入和实例化类。让我们分解一下如何正确执行此操作,以及如何构建代码以获得更好的组织。
理解问题
-
循环导入:
当两个模块尝试相互导入时,就会发生循环导入。在的情况下,
LoginOrReg
尝试导入HabitTracker
,而HabitTracker
尝试导入LoginOrReg
。这会造成一个循环,Python 不知道如何解决。 -
不必要的实例化:
在彼此的类方法中创建
HabitTracker
和LoginOrReg
的新实例。这没有必要,会导致意外行为。理想情况下,希望每个应用程序实例只有一个每个类。
解决方案
- 重构: 更好的方法是创建一个单独的文件来管理的应用程序流程和实例化:
```python # main.py import tkinter as tk import customtkinter from LoginOrReg import LoginOrReg from HabitTracker import HabitTracker
class App: def init (self): self.root = tk.Tk() self.root.withdraw() # initially hide the root window
# Create instances of your classes
self.login_manager = LoginOrReg(self)
self.habit_tracker = HabitTracker(self)
# Start with the login screen
self.login_manager.login()
self.root.mainloop()
if name == " main ": app = App() ```
- 修改的类:
```python # LoginOrReg.py import customtkinter
class LoginOrReg: def init (self, app): self.app = app # Store reference to the main app # ... your database connection (replace placeholders) self.db = mysql.connector.connect(host=' ', user=' ', password=' ', database=" ") self.cursor = self.db.cursor()
def login(self):
# ... your login window code ...
def log_user_in(self):
# ... your login logic ...
if self.row_count == 1:
# ... fetch user data ...
self.app.habit_tracker.user_id = self.user_id
self.app.habit_tracker.main_menu()
self.login_window.destroy() # Close login window
else:
# ... handle invalid login ...
```
```python # HabitTracker.py import customtkinter
class HabitTracker: def init (self, app): self.app = app # Store reference to the main app self.user_id = None # ... your database connection (replace placeholders) self.db = mysql.connector.connect(host=' ', user=' ', password=' ', database=" ") self.cursor = self.db.cursor()
def main_menu(self):
if self.user_id is None:
# Handle the case where the user is not logged in.
# Maybe show an error message.
return
self.main_window = customtkinter.CTk()
# ... (rest of your main_menu code)
```
解释
-
main.py
: - 此文件现在控制的应用程序流程。
-
它首先实例化
LoginOrReg
和HabitTracker
。 -
然后它调用
login_manager.login()
开始登录流程。 -
LoginOrReg.py
: -
LoginOrReg
类现在接收app
实例作为参数。这允许它访问和控制其他部分,例如HabitTracker
。 -
成功登录后,它会调用
app.habit_tracker.main_menu()
并关闭登录窗口。 -
HabitTracker.py
:-
HabitTracker
类也接收app
实例作为参数。 -
现在有一个
user_id
属性,该属性在成功登录后由LoginOrReg
类设置。
-
如何运行:
-
将修改后的代码保存为三个文件:
main.py
、LoginOrReg.py
和HabitTracker.py
。 -
从的终端运行
python main.py
。
这提供了一种更清晰、更有条理的方式来管理的 Python GUI 应用程序中的类和应用程序流。
标签:python,file,oop,methods From: 78792248