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

如何在Python Panel中保存FileInput上传的多文件?

Panel FileInput 多文件上传保存解决方案

问题说明

使用Panel的FileInput组件开启multiple=True实现多文件上传后,能正常获取文件名列表,但调用save()方法时触发如下错误:

TypeError: FileInput contains a single files but a list of filenames was given. Please provide a single filename or file-like object.

用户原实现代码:

import panel as pn
import io

pn.extension()

file_input = pn.widgets.FileInput(accept='.csv', sizing_mode='stretch_width',
                                  multiple=True)

def get_files(files = None):
    if file_input.filename == None:
        selector = pn.widgets.MultiSelect(
        name='Select files', sizing_mode='stretch_width',
        options=['Add your files here'])
        return selector
    else:
        selector = pn.widgets.MultiSelect(
        name='Select files', sizing_mode='stretch_width',
        options=file_input.filename)
        return selector

upload_files = pn.bind(get_files, file_input, watch=True)

解决方案

当FileInput开启多文件上传时,save()方法仅支持单文件操作,需通过遍历files属性处理每个上传文件:

核心思路

  • file_input.files:存储所有上传文件的二进制对象,每个对象支持read()方法读取内容
  • file_input.filename:对应每个文件的原始文件名,用于命名保存后的文件
  • 通过zip配对文件对象与文件名,逐个处理保存

完整实现代码

import panel as pn
import io

pn.extension()

file_input = pn.widgets.FileInput(accept='.csv', sizing_mode='stretch_width',
                                  multiple=True)

def get_files(files = None):
    if not file_input.filename:
        selector = pn.widgets.MultiSelect(
            name='Select files', sizing_mode='stretch_width',
            options=['Add your files here'])
        return selector
    else:
        selector = pn.widgets.MultiSelect(
            name='Select files', sizing_mode='stretch_width',
            options=file_input.filename)
        return selector

def save_uploaded_files():
    if file_input.files and file_input.filename:
        # 遍历每个上传文件,配对文件对象与文件名
        for file_obj, filename in zip(file_input.files, file_input.filename):
            # 方式1:保存到本地磁盘
            with open(filename, 'wb') as local_file:
                local_file.write(file_obj.read())
                print(f"文件 {filename} 已保存")
            
            # 方式2:保存到内存BytesIO(用于后续数据处理,如pandas读取)
            # mem_file = io.BytesIO()
            # mem_file.write(file_obj.read())
            # mem_file.seek(0)  # 重置文件指针到开头
            # 示例:用pandas读取内存中的CSV
            # import pandas as pd
            # df = pd.read_csv(mem_file)
            # print(f"已读取文件 {filename} 的数据")

# 绑定文件选择与保存逻辑
upload_files = pn.bind(get_files, file_input, watch=True)
pn.bind(save_uploaded_files, file_input, watch=True)

# 展示仪表盘
pn.Column(file_input, upload_files).servable()

关键注意事项

  • 确保file_input.files和file_input.filename都不为空时再执行保存逻辑,避免空列表报错
  • 若使用内存保存方式,写完内容后需调用seek(0)重置文件指针,否则后续读取会从文件末尾开始
  • 可根据业务场景选择本地保存或内存保存方式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:22:50