使用exec()创建带验证的tkinter.Entry时触发SyntaxError报错
问题根因
报错由两处代码错误直接引发:
- 拼接的exec代码里,
tkinter.Entry的关键字参数错误添加了self.前缀,写成了self.validatecommand。Python规定函数传入的关键字参数必须是合法标识符,不允许出现属性访问的点号,解释器解析到self.validatecommand = xxx的写法时,会判定为表达式内部夹带赋值操作,直接抛出你看到的SyntaxError: expression cannot contain assignment, perhaps you meant "=="?异常。 - 代码存在变量名不匹配问题:你提前注册的输入验证函数存储在
self.percentage_validification属性中,但拼接的代码里引用的是不存在的self.validation属性,即便修正语法错误也会触发属性不存在的运行时异常。
可行实现方案
方案1:修正exec拼接逻辑(不推荐)
如果要保留原有exec动态生成属性的写法,只需要修正参数名和变量引用即可,代码如下:
def number_validate(char): return char.isdigit() self.percentage_validification = self.root.register(number_validate) name = "Percentage" exec(f"self.{name}_box = tkinter.Entry(self.root, validate='key', validatecommand=(self.percentage_validification, '%S'))")
方案2:用字典统一管理动态控件(推荐)
exec动态生成变量存在安全隐患、后续维护成本高,遍历配置生成控件时更推荐用字典统一存储所有控件实例,不需要做字符串转代码的操作,逻辑更可控:
def number_validate(char): return char.isdigit() # 提前注册验证命令 number_validate_cmd = self.root.register(number_validate) # 初始化控件存储字典,所有动态生成的控件都存在这里 self.dynamic_widgets = {} name = "Percentage" # 直接创建控件存入字典,不需要exec self.dynamic_widgets[f"{name}_box"] = tkinter.Entry( self.root, validate="key", validatecommand=(number_validate_cmd, "%S") ) # 后续操作控件直接从字典取值即可,示例: # self.dynamic_widgets["Percentage_box"].pack(padx=10, pady=10)
如果后续要给不同字段绑定不同的验证规则,只需要在你存储控件配置的元组里把对应验证命令也作为配置项传入,遍历的时候直接读取配置创建控件即可,不需要做字符串拼接。
内容的提问来源于stack exchange,提问作者MikkelDA
相关产品推荐
相关产品推荐

