You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask应用中exec定义的变量无法找到,但调试器可访问

问题分析与修复方案

核心问题拆解

  1. exec()的作用域陷阱:你用exec(f"test = CafeForm().{form_item}.data")试图定义变量,但exec执行的代码不会自动注入当前函数的局部作用域,后续访问test必然触发NameError。更关键的是,你在这里新建了一个空的CafeForm实例,根本拿不到用户提交的表单数据。
  2. 表单实例误用:要获取用户提交的评分,必须使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:21:13