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

如何修复Python中UnboundLocalError: 'Auto_field'未赋值即引用错误

错误原因分析

UnboundLocalError: local variable 'Auto_field' referenced before assignment 出现的核心原因是:
在update_chart函数的分支逻辑中,仅当选中特定类别时才定义对应变量(比如只有选「重電機器受注生産品」时才定义Auto_field),但后续构建field_0字典时直接引用了所有分支的变量——当选中其他类别时,未被赋值的变量就会触发未定义错误。

另外原代码还存在两处笔误:

  • 全局变量名産業用汎用産業用汎用電気機器計应改为産業用汎用_産業用汎用電気機器計
  • 全局变量名産業用汎用回転の駆動機器計应改为産業用汎用回転駆動機器計(对应else分支里的引用)
修复方案

方案1:提前初始化所有变量(快速修复)

在update_chart函数的分支判断前,先初始化所有需要用到的变量,确保无论走哪个分支,变量都有定义:

def update_chart(evt=None):
    
    global field_0
    global data_item
    
    # 提前初始化所有可能用到的变量,避免未定义错误
    Fridge_field = None
    Fridgebig_field = None
    Auto_field = None
    Construction_field = None
    IETotal_field = None
    Rotating_field = None
    
    if input_1.value == "民生用電気機器":
        Fridge_field = 民生用電気機器_電気冷蔵庫
        Fridgebig_field = 民生用電気機器_電気冷蔵庫うち401L以上
    

    elif input_1.value == "重電機器受注生産品":
        Auto_field = 重電機器受注生産品_自動車
        Construction_field = 重電機器受注生産品_建設業
        
    else: 
        IETotal_field = 産業用汎用_産業用汎用電気機器計
        Rotating_field = 産業用汎用回転駆動機器計
   
    
    field_0 = {
        '電気冷蔵庫': Fridge_field ,
        '電気冷蔵庫 うち401L以上': Fridgebig_field ,
        '自動車': Auto_field ,
        '建設業': Construction_field ,
        '産業用汎用電気機器計': IETotal_field ,
        '回転・駆動機器計': Rotating_field}
    
    # 后续代码保持不变...

同时修正全局变量的笔误:

# 修正后的全局变量定义
産業用汎用_産業用汎用電気機器計 = {'Industrial Equipment Total': 'JEESTOTL Index'}
産業用汎用回転駆動機器計 = {'Industrial Equipment - Rotating/driving equipment meter' :'JEESMREG Index'}

方案2:重构字段映射(更优雅的长期方案)

将类别与字段的映射关系统一整理成字典,避免分散的变量定义,同时让逻辑更清晰:

def chart_returns_different_country(bq):
    # 统一定义类别-字段的映射关系
    category_field_map = {
        "民生用電気機器": {
            '電気冷蔵庫': {'House Appliance Refridgerator': 'JNESHQER Index'},
            '電気冷蔵庫 うち401L以上': {'House Appliance Refridgerator Over 401 Litre':'JNESHQRO Index'}
        },
        "重電機器受注生産品": {
            '自動車': {'Heavy Electric Equipment - Automobiles': 'JPCITOTL Index'},
            '建設業': {'Heavy Electric Equipment - Construction':'JNHECONS Index'}
        },
        "産業用汎用": {
            '産業用汎用電気機器計': {'Industrial Equipment Total': 'JEESTOTL Index'},
            '回転・駆動機器計': {'Industrial Equipment - Rotating/driving equipment meter' :'JEESMREG Index'}
        }
    }
    
    count_list = list(category_field_map.keys())
    # 默认加载第一个类别的字段作为初始选项
    field_list = list(category_field_map[count_list[0]].keys())

    input_1 = widgets.Dropdown(options = count_list,
        value = '民生用電気機器',
        description = 'Choose a country', 
        style={'description_width': 'initial'},
        layout=Layout(width='50%', height='40px')
    )

    input_2 = widgets.Dropdown(options = field_list,
                              value=field_list[0],
                              description='機器')

    # 新增:当input_1切换时,动态更新input_2的选项
    def update_field_options(evt):
        selected_category = input_1.value
        input_2.options = list(category_field_map[selected_category].keys())
        input_2.value = input_2.options[0]
    input_1.observe(update_field_options, names='value', type='change')

    # 日期选择器代码保持不变...
    from datetime import date, datetime
    start_time = date(2020, 4, 30)
    input_3 = widgets.DatePicker(description='Choose start date', disabled=False, value=start_time)

    end_time = datetime.today()
    input_4 = widgets.DatePicker(description='Choose end date', disabled=False, value=end_time)

    # 图表初始化代码保持不变...
    fig = go.Figure()
    fig.update_traces(textfont_size=18, textangle=0, textposition ="outside", cliponaxis =False)
    fig.layout.xaxis.title.text = 'Date'
    fig.layout.yaxis.title.font.size=18
    fig.update_layout(template ='plotly_dark',height=700)
    fig.update_layout(xaxis={'side':'bottom'})
    fig.update_xaxes(tickfont_size=18, tickangle=0)
    fig.update_yaxes(tickfont_size=18)
    fig.update_layout(xaxis=dict(showgrid=False), yaxis=dict(showgrid=False))
    fig = make_subplots(specs=[[{"secondary_y": True}]])

    fig_w = go.FigureWidget(fig)

        
    def update_chart(evt=None):
        global field_0
        global data_item
        
        selected_category = input_1.value
        selected_field = input_2.value
        
        # 直接从映射字典中获取对应字段,无需定义大量变量
        selected_index = category_field_map[selected_category][selected_field]
        data_item = {'Value': bq.data.px_last(dates=bq.func.range(input_3.value, input_4.value),fill='NA',per='M')}
        
        global bql_request
        bql_request = bql.Request(list(selected_index.values()), data_item)
        df = bql.combined_df(bq.execute(bql_request))
        df.index = df.index.map(dict(zip(selected_index.values(), selected_index.keys())))
        df = df.reset_index()
        df = df.pivot(index='DATE', columns='ID', values='Value')
        df_plot = df.copy()
        df_plot.reset_index(inplace=True)
        df_plot.set_index('DATE', inplace=True)
        
        x = df_plot.index
        fig_w.data= []
       
        for i in range(len(df_plot.columns.values)):
            if i == 0:
                fig_w.add_trace(go.Scatter(name= df_plot.columns.values[0], x= x, y= df_plot[df_plot.columns.values[0]], mode='lines',  yaxis='y1'), secondary_y=False)
                
            else:
                try:
                    fig_w.add_trace(go.Scatter(name=df_plot.columns.values[i], x= x, y= df_plot[df_plot.columns.values[i]], mode='lines', yaxis='y2'), secondary_y=True)
                except:
                    pass
        y_label1  =  df_plot.columns.values[0] + ' Scale'  
        y_label2 = 'Others'
        fig_w.update_layout(yaxis = dict(title = y_label1), yaxis2 = dict(title = y_label2))
                            
        fig_w.layout.xaxis.title.text = 'Date'
        
        fig_w.update_xaxes(tickangle=45)
        fig_w.update_layout(template='plotly_dark', height=700, font_family="Arial", legend_font_size=16, font=dict(
            family="Arial",
            size=18, ))
        fig_w.update_layout(xaxis=dict(tickvals=x))
        fig_w.for_each_xaxis(lambda x: x.update(showgrid=False))
        fig_w.for_each_yaxis(lambda x: x.update(showgrid=False))

    update_chart()

    input_1.observe(update_chart, names='value', type='change')
    input_2.observe(update_chart, names='value', type='change')
    input_3.observe(update_chart, names='value', type='change')
    input_4.observe(update_chart, names='value', type='change')
    
    # 重构bql_request的生成逻辑,遍历所有类别和字段
    bql_request = []
    for category in category_field_map:
        for field, index_map in category_field_map[category].items():
            req = bql.Request(list(index_map.values()), data_item)
            bql_request.append(str(req))
    return {'Chart': widgets.VBox([input_1, input_2, input_3, input_4, fig_w]), 'BQL Query': '\n'.join(bql_request)}

这个方案的优势:

  • 消除了分散的变量定义,彻底避免未定义错误
  • 实现了下拉框联动:选择不同类别时,字段下拉框自动更新对应选项
  • 代码结构更清晰,后续新增类别或字段只需修改category_field_map即可
额外注意事项
  • 确保date和datetime模块已导入,可在函数开头添加from datetime import date, datetime
  • 确保widgets、go、make_subplots、bql等依赖已正确导入

内容的提问来源于stack exchange,提问作者HoangIta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:07:02