Flask应用中exec定义的变量无法找到,但调试器可访问
问题分析与修复方案
核心问题拆解
- exec()的作用域陷阱:你用
exec(f"test = CafeForm().{form_item}.data")试图定义变量,但exec执行的代码不会自动注入当前函数的局部作用域,后续访问test必然触发NameError。更关键的是,你在这里新建了一个空的CafeForm实例,根本拿不到用户提交的表单数据。 - 表单实例误用:要获取用户提交的评分,必须使用
add_cafe路由里已经实例化并接收了请求数据的form对象,而不是重新创建新实例。
修复后的完整代码调整
1. 替换exec的评分转换函数
完全抛弃exec,用直白的方式处理评分转emoji的逻辑:
def get_rating_emoji(rating, emoji): # 0分返回✘,其他分数返回对应数量的emoji if int(rating) == 0: return "✘" return emoji * int(rating)
2. 修改add_cafe路由逻辑
使用用户提交的表单实例,正确转换评分并写入CSV:
@app.route('/add', methods=["GET", "POST"]) def add_cafe(): form = CafeForm() if form.validate_on_submit(): # 转换各评分字段为emoji格式 coffee_emoji = get_rating_emoji(form.coffee.data, "☕") wifi_emoji = get_rating_emoji(form.wifi.data, "💪") power_emoji = get_rating_emoji(form.power.data, "🔌") with open("cafe-data.csv", encoding="utf-8", mode="a", newline='') as csv_file: # 添加换行符避免数据挤在同一行,同时兼容Windows系统 csv_file.write(f"{form.cafe_name.data},{form.location.data},{form.open_time.data},{form.close_time.data},{coffee_emoji},{wifi_emoji},{power_emoji}\n") # 提交后重定向到列表页,防止重复提交 return redirect(url_for('cafes')) return render_template('add.html', form=form)
3. 额外优化点
- 给CSV写入添加
newline='',避免Windows环境下生成空行 - 表单提交成功后重定向到咖啡馆列表页,遵循POST/REDIRECT/GET标准模式
- 0分返回
✘,完全匹配题目示例要求
为什么exec在这里完全没必要?
exec适合处理极复杂的动态代码场景,但你的需求只是访问表单字段属性,用getattr(form, form_item).data就能直接实现,比如getattr(form, 'coffee').data就可以拿到咖啡评分,代码更清晰、安全,也不会出现作用域问题。
内容的提问来源于stack exchange,提问作者SmallCoder12
相关产品推荐
相关产品推荐

