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

Bokeh CustomJS解构实例错误:Jupyter正常运行但Streamlit环境失效求助

报错原因分析

这个报错本质是Bokeh尝试遍历非数组类型的数据源字段,核心诱因有2个:

  • 变量x未做兜底校验:你在if分支内用var声明x,如果选择框的值没有匹配到任何src里的记录,x会是undefined,此时取src.data['mean'][undefined]返回的是undefined,赋值给src2的字段后,Bokeh内部需要迭代该字段渲染时就会触发非可迭代实例的报错。Jupyter环境可能默认做了空值兼容,而Streamlit的Bokeh组件序列化逻辑更严格,所以会报错。
  • 嵌套数组序列化差异:你提到src的单元格存储的是列表,Streamlit传递Bokeh的ColumnDataSource时,嵌套列表可能被序列化为类数组对象而非标准JS数组,导致Bokeh识别为非可迭代类型。
修复方案
  1. 替换var为块级作用域的let声明x,提前赋初始值,循环结束后做无匹配校验,无匹配时直接终止回调逻辑。
  2. 匹配到对应索引后直接跳出循环,避免后续循环意外覆盖x的值。
  3. 用Array.from()包裹赋值的数组,确保传入src2的是标准可迭代JS数组。
  4. 操作src2.data前先做判空,避免数据源未初始化的异常。
修改后的回调代码
callback = CustomJS(args=dict(select=select,src=src,src2=src2), code='''
      // 提前初始化x,赋无效初始值
      let x = -1;
      const selectVal = Number(select.value);

      for (let i = 0; i < src.get_length(); i++) {
        const nme = src.data['nme'][i];
        const targetVal = nme === 'L' ? src.data['i.l'][i] : src.data['i.lo'][i];
        if (targetVal === selectVal) {
            x = i;
            // 匹配到就跳出,避免后续覆盖
            break;
        }
      }

      // 无匹配直接终止,避免后续报错
      if (x === -1 || !src2.data) return;

      // 用Array.from确保是标准数组,兼容序列化差异
      src2.data['mean'] = Array.from(src.data['mean'][x]);
      src2.data['10'] = Array.from(src.data['10'][x]);
      src2.data['90'] = Array.from(src.data['90'][x]);

      src2.change.emit();
''')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:51:03