Python tkinter报错:外部作用域的lbl变量在赋值前被引用
问题解析:外部作用域报错与代码问题说明
一、“外部作用域”指什么?
这里的外部作用域就是你定义函数display_each之外的全局作用域——也就是代码顶部写global lbl和lbl = tk.Label(tab1)的层级。函数内部属于局部作用域,报错里的“enclosing scope”(外部作用域)就特指这个全局层级。
二、代码问题出在哪?
- 作用域判定冲突:函数
display_each的else分支里写了lbl = tk.Label(tab1, ...),这行代码会让Python自动把lbl判定为函数内部的局部变量,而非引用全局的lbl。 - 局部变量未赋值先引用:if分支里先调用了
lbl.config(...),但此时局部的lbl还没被创建(只有else分支才会赋值),Python因此报错“局部变量在赋值前被引用”。 - 全局声明未生效:全局作用域的
global lbl对函数内部无效,若要在函数里操作全局变量lbl,必须在函数开头再次声明global lbl。
三、修复方案
方案1:复用全局Label(推荐)
如果想一直用全局定义的lbl,不要在函数里重新赋值,统一用config修改文本:
global lbl lbl = tk.Label(tab1) def display_each(value): global lbl # 函数内声明引用全局变量 ID = value print(ID) add = 0 if ID == 1: add = 5 elif ID == 2: add = 6 elif ID == 3: add = 9 c.execute(f''' SELECT * FROM Workout WHERE Program_Routine_ID = {ID} ''') x = c.fetchall() for i in range(len(x)): c.execute(f''' SELECT ID,Name,Equipment,Difficulty,Muscle FROM Exercise WHERE Workout_ID = {i+(ID+add)} ''') y = c.fetchall() print(f'{x[i][2].upper()} workout.{len(y)} exercises:') print() for j in range(len(y)): if y[j][2] in ("None", "none"): lbl.config(text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires no equipment. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}') else: # 改成config修改文本,不再重新创建Label lbl.config(text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires {y[j][2]}. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}') lbl.pack()
方案2:函数内创建局部Label
如果需要每次创建新的Label,确保先赋值再引用,或换变量名避免冲突:
global lbl lbl = tk.Label(tab1) def display_each(value): ID = value print(ID) add = 0 if ID == 1: add = 5 elif ID == 2: add = 6 elif ID == 3: add = 9 c.execute(f''' SELECT * FROM Workout WHERE Program_Routine_ID = {ID} ''') x = c.fetchall() for i in range(len(x)): c.execute(f''' SELECT ID,Name,Equipment,Difficulty,Muscle FROM Exercise WHERE Workout_ID = {i+(ID+add)} ''') y = c.fetchall() print(f'{x[i][2].upper()} workout.{len(y)} exercises:') print() for j in range(len(y)): # 换局部变量名,避免和全局lbl冲突 if y[j][2] in ("None", "none"): local_lbl = tk.Label(tab1, text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires no equipment. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}') else: local_lbl = tk.Label(tab1, text = f'{y[j][0]+1} ) {y[j][1]}.\n Requires {y[j][2]}. \n It is {y[j][3]} difficulty.\n It works the {y[j][4]} muscles with workout id {i+(ID+add)}') local_lbl.pack()
内容的提问来源于stack exchange,提问作者Armaan Khaitan
相关产品推荐
相关产品推荐

