为什么tkinter回调函数save3报pliktyped变量未定义的NameError?
触发save3回调时的Tkinter报错
点击保存按钮触发回调时,抛出的完整异常栈如下:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\tkinter\__init__.py", line 1705, in __call__ return self.func(*args) File "C:\Users\Medion\Desktop\PY - DOS GUI\OKNO.py", line 59, in save3 d = pliktyped.get() NameError: name 'pliktyped' is not defined
问题根因
报错由Python嵌套函数的作用域访问规则导致:
pliktyped是在save2函数内部创建的输入框控件,属于save2的局部变量,仅在save2的执行作用域内可访问,save2执行完成后该变量就会被回收save3和save2是同属外层save函数的平级子函数,平级函数之间无法直接读取对方的局部变量- 同理,
save3中用到的目标文件路径变量plek也是在save2内部定义的局部变量,同样存在跨作用域无法访问的问题
修复方法
需要把pliktyped和plek的作用域提升到外层save函数层级,通过nonlocal关键字声明子函数对变量的引用关系,同时修正原代码中提前清空目标文件的逻辑漏洞,修改后的参考代码如下:
def save(): # 在外层函数中声明需要跨子函数共享的变量,初始值为空 plek = None pliktyped = None def save3(): # 声明引用外层作用域的变量,而非在当前函数内创建同名局部变量 nonlocal plek, pliktyped # 增加空值校验,避免界面未完全初始化时触发异常 if not plek or not pliktyped: return input_content = pliktyped.get() # 用上下文管理器打开文件,自动完成文件句柄的释放 with open(plek, 'w') as target_file: target_file.write(str(input_content)) menu() def save2(): nonlocal plek, pliktyped # 仅获取用户输入的目标文件路径,不提前打开文件避免误清空内容 plek = str(pliksave.get()) textsave2 = Label(okno, text="Text to be typed").grid(column=0, row=0) pliktyped = Entry(okno, width=10) pliktyped.grid(column=0, row=1) save_btn = Button(okno, text="Type this text to file", command=save3).grid(column=1, row=1) # 原有界面初始化逻辑保持不变 for widget in okno.winfo_children(): widget.destroy() foldery = Label(okno, text=folder, bg='lightblue').grid(column=0, row=3) folderyCo = Label(okno, text='Files:', bg='lightblue').grid(column=0, row=2) textsave = Label(okno, text="File to edit:").grid(column=0, row=0) pliksave = Entry(okno, width=10) pliksave.grid(column=0, row=1) goSave = Button(okno, text="Edit this file", command=save2).grid(column=1, row=1)
代码优化提示
- 原代码在
save2中直接执行open(plek, 'w')存在逻辑漏洞:只要用户点击"Edit this file"按钮,目标文件就会被立即清空,哪怕后续没有输入任何内容、没有完成保存操作,上述修改已经将文件写入逻辑调整为仅在用户点击最终保存按钮时执行 - 打开文件时使用
with上下文管理器,可以避免程序异常退出时文件句柄未正常释放的问题
内容的提问来源于stack exchange,提问作者src_guy
相关产品推荐
相关产品推荐

