如何无循环依赖导入Python模块全局变量username?
Fixing 'SignIn is not callable' Error & Avoiding Circular Dependencies
Let's break down your issues and fix them step by step:
- 'SignIn is not callable': You’re trying to invoke the
SignInmodule like a function (SignIn())—modules aren’t callable, which is why this error pops up. - Circular Dependencies: This happens when modules try to import each other. We’ll fix this by enforcing a safe one-way import flow.
- Timing Issue: You’re trying to access
SignIn.usernamebefore the user has actually entered a value via the Tkinter window.
Step 1: Refactor the SignIn Module
We’ll wrap the Tkinter setup in a function, ensure the login function properly captures and cleans the username, and close the window after login so your main program can resume.
# SignIn.py import tkinter def login(): # Capture and sanitize the username input global username username = entry_user.get().strip() win.destroy() # Close the login window to unblock the main program def setup_login_window(): global win, entry_user win = tkinter.Tk() win.title("Employee Login") # Add clear UI elements for better user experience user_label = tkinter.Label(win, text="Username:") user_label.pack(pady=(10, 0)) entry_user = tkinter.Entry(win) entry_user.pack(pady=5) # Add a login button tied to the login function login_btn = tkinter.Button(win, text="Login", command=login) login_btn.pack(pady=(5, 10)) win.mainloop() # Start the Tkinter event loop # Test the module directly if run standalone if __name__ == "__main__": setup_login_window() print(f"Entered username: {username}")
Step 2: Update Your Main Program
Now we’ll call the setup function from SignIn instead of the module itself, wait for the user to complete login, then safely access the username for your SQLite query.
# Main program import sqlite3 import SignIn import Password_database # Launch the login window and wait for user input SignIn.setup_login_window() # Handle cases where the user closes the window without logging in try: username = SignIn.username except AttributeError: print("Error: No username entered. Exiting.") exit() # Connect to SQLite and execute your query (cleaned up redundant fetch calls) conn = sqlite3.connect('passwordDbase.db') c = conn.cursor() c.execute('SELECT * FROM passwordDbase WHERE employee_username = ?', (username,)) rows = c.fetchall() message = 'correct' if len(rows) == 1 else '' print(message) # Clean up database connections properly conn.commit() c.close() conn.close()
Why This Works
- No More 'SignIn is not callable': We’re calling the
setup_login_window()function from the module, not the module itself. - No Circular Dependencies: The
SignInmodule doesn’t import your main program—only the main program importsSignIn, creating a safe one-way dependency. - Guaranteed Username Value: The Tkinter event loop blocks the main program until the login window is closed, so
usernamewill be set (or we handle the edge case where it’s not).
Bonus Best Practices
- Avoid Global Variables: For cleaner, more maintainable code, wrap the login logic in a class:
Then use it in your main program:class LoginApp: def __init__(self): self.username = None self.win = tkinter.Tk() self.entry_user = tkinter.Entry(self.win) # ... rest of UI setup ... def login(self): self.username = self.entry_user.get().strip() self.win.destroy() def run(self): self.win.mainloop()login_app = SignIn.LoginApp() login_app.run() username = login_app.username - Validate Input: Add checks for empty usernames before running the database query.
- Optimize Database Queries: If you only need to check if the username exists, use
SELECT EXISTS(...)instead of fetching all rows—it’s more efficient.
内容的提问来源于stack exchange,提问作者nhm64 rtwh
相关产品推荐
相关产品推荐

