求助:PageOne实例报AttributeError:无'scann'属性问题排查
解决AttributeError: PageOne instance has no attribute 'scann'问题
我在运行bash脚本runfocus时遇到了这个错误:
AttributeError: PageOne instance has no attribute 'scann'
我始终无法找出报错原因,我的代码如下:
class PageOne(tk.Frame): def __init__(self, parent, controller): running = False # Global flag tk.Frame.__init__(self, parent) self.controller = controller button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) strt = tk.Button(self, text="Start Scan", command=self.start) stp = tk.Button(self, text="Stop", command=self.stop) button.pack() strt.pack() stp.pack() self.after(1000, self.scann) # After 1 second, call scanning def scann(self): if running: sub.call(['./runfocus'], shell=True) self.after(1000, self.scann) def start(self): """Enable scanning by setting the global flag to True.""" global running running = True def stop(self): """Stop scanning by setting the global flag to False.""" global running running = False
嘿,我帮你梳理下问题根源,其实是两个小细节没处理到位:
1. 方法缩进错误(核心报错原因)
看你贴的代码,scann、start、stop这三个方法的缩进是不是没和__init__方法对齐?Python是靠缩进识别类成员的,如果这些方法没有正确缩进在class PageOne的作用域内,那PageOne的实例自然找不到scann这个属性,直接就抛出AttributeError了。
解决方式: 确保这三个方法的缩进和__init__完全一致,都属于class PageOne的内部方法。
2. running变量的作用域问题
你在__init__里定义的running = False是局部变量,后面start/stop里用global running试图修改全局变量,但这个全局变量根本没初始化,而且scann里直接调用running也会找不到它。
解决方式: 把running改成类的实例属性,用self.running来访问,这样所有类方法都能正确读写这个状态:
class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) self.controller = controller self.running = False # 改为实例属性 # 按钮代码保持不变 button = tk.Button(self, text="Go to the start page", command=lambda: controller.show_frame("StartPage")) strt = tk.Button(self, text="Start Scan", command=self.start) stp = tk.Button(self, text="Stop", command=self.stop) button.pack() strt.pack() stp.pack() self.after(1000, self.scann) def scann(self): if self.running: # 使用self.running判断状态 sub.call(['./runfocus']) # 去掉shell=True更安全 self.after(1000, self.scann) def start(self): self.running = True # 直接修改实例属性,无需global def stop(self): self.running = False # 同样修改实例属性
另外提个小细节:调用sub.call时已经用了列表形式的参数,就没必要加shell=True了,这样能避免一些不必要的安全风险。
按照这两点修改后,应该就能解决这个报错了!
内容的提问来源于stack exchange,提问作者user9846250
相关产品推荐
相关产品推荐

