Python主文件导入自定义函数文件报accounts未定义及属性错误如何解决
问题修复方案
核心问题原因
- 不同Python模块的全局变量作用域互相独立,函数文件无法直接访问主文件定义的全局变量
accounts - 按钮绑定的command写法错误,导致函数在页面初始化时就直接执行,而非点击时触发
- 主文件的
Goode_brothers类没有定义email、password、email2等输入框实例属性,函数读取时找不到对应属性报错 - 函数文件中直接使用的
root变量未定义,同样属于跨模块变量访问问题
具体修复步骤
1. 修改函数文件(functioon.py)
无需依赖任何外部全局变量,所有需要的内容要么从传入的类实例取,要么在函数内部生成:
from tkinter import * from PIL import Image, ImageTk def save_info(self): self.email_reg = str(self.email2.get()) self.pass_word = str(self.password2.get()) print(self.email2) file = open('emails.txt', 'a+') # 写入用户凭证,邮箱和密码用逗号分隔 file.write(self.email_reg + ', ' + self.pass_word + '\n') file.close() # 操作完成后必须关闭文件 def read_info(self): # 直接在函数内部生成账号列表,不需要依赖外部的accounts全局变量 accounts = [] with open("emails.txt") as read_ep: for line in read_ep: accounts.append(line.strip().split(", ")) credential = [self.email.get(), self.password.get()] if credential in accounts: self.open_menu() # 如果需要主文件也使用accounts列表,可在此处加上 return accounts else: # root从self的属性取,主文件类初始化时会把根窗口存为self.root self.ep_notexist = Label(self.root, text = "您的邮箱或密码不正确,请重试", font=("open sans", "8")) self.ep_notexist.place(x = 210, y = 300) self.ep_notexist.after(4000, self.ep_notexist.destroy) self.email.delete(0, END) self.password.delete(0, END)
2. 修改主文件
首先修正按钮command的绑定写法,然后补全类缺失的属性:
import functioon from tkinter import * from PIL import Image, ImageTk # 此处补充你原本定义的全局变量 BORDER = 0 CURSOR = "hand2" class Goode_brothers: def __init__(self, parent): self.root = parent # 把根窗口存为类属性,方便函数里调用 self.my_frame = Frame(parent) self.my_frame.pack() self.background = Image.open('images\\food.jpg') self.background_image = ImageTk.PhotoImage(self.background) self.img = Label(parent, image = self.background_image) self.img.place(x = -26, y =0) # === 补全你缺失的登录页邮箱、密码输入框定义,必须用self.前缀存为类属性 === self.email = Entry(parent) self.email.place(x=200, y=200) # 位置根据你的页面需求自行调整 self.password = Entry(parent, show="*") self.password.place(x=200, y=250) # 位置根据你的页面需求自行调整 self.img_login = PhotoImage(file = 'new-dip-project\\button (3).png') # 修正command写法,用lambda包裹避免页面初始化时直接执行函数 self.login_button = Button(parent,image = self.img_login, command = lambda: functioon.read_info(self), bd = BORDER, cursor = CURSOR, bg = '#3b353b', activebackground = '#3b353b') self.login_button.place(x = 275, y = 340) # 你原本的注册页面逻辑,要把注册邮箱、密码输入框存为self.email2、self.password2 def register_page(self): self.root2 = Toplevel(self.root) self.email2 = Entry(self.root2) self.email2.place(x=80, y=80) self.password2 = Entry(self.root2, show="*") self.password2.place(x=80, y=110) Button(self.root2, text="提交注册", command=self.create_pass).place(x=80, y=170) def create_pass(self): self.password_length = Label(self.root2, text = '') self.password_length.place(x = 80, y = 140) self.pass_word = str(self.password2.get()) if len(self.pass_word) >= 8: functioon.save_info(self) self.registered = Label(self.root2, text = '注册成功,窗口将自动关闭', font=("open sans", "8")) self.registered.place(x = 80, y = 140) self.root2.after(1500, self.root2.destroy) else: self.password_length.configure(text="密码长度至少为8位,请重试", font=("open sans", "8")) def open_menu(self): # 补充你自己的登录成功后打开菜单的逻辑 pass # 窗口启动逻辑 if __name__ == "__main__": root = Tk() root.geometry("700x500") app = Goode_brothers(root) root.mainloop()
其他注意事项
- 所有需要在类外部函数访问的输入框、窗口对象,都必须用
self.前缀存为类的实例属性,不能仅定义局部变量 - 按钮的command参数如果要传参,必须用
lambda:或者functools.partial包裹,否则会在定义按钮时直接执行函数,而非点击时触发 - 不同模块的全局变量不能直接互相访问,需要用到的变量要么作为参数传入函数,要么在函数内部定义生成
内容的提问来源于stack exchange,提问作者dfgdf dzfgdf
相关产品推荐
相关产品推荐

