Python上传文件代码报IsADirectoryError: [Errno 21]错误原因及解决
报错根因
你触发IsADirectoryError: [Errno 21] Is a directory: '/'的核心原因是路径迭代逻辑完全错误:os.path.abspath(path)的返回值是字符串类型的绝对路径,你直接对字符串执行for p in <字符串>操作时,Python会逐个遍历字符串中的单个字符。你的目标路径以/开头,迭代拿到的第一个元素就是根目录路径/,当你尝试执行open('/', 'rb')时,系统检测到该路径是目录而非可读取的文件,就会抛出对应错误。
你的代码还存在3个明显逻辑问题:
- 未正确获取目录下的文件列表:现有写法完全没有读取目标文件夹内的文件,只是在拆分路径字符串的单个字符
- 文件上传逻辑错误:提前构造
files字典时重复占用同一个file键,且未关闭打开的文件,会造成文件句柄泄漏 - 循环逻辑错误:遍历过程中没有逐个上传单个文件,每次请求都传入全量打开的文件对象,逻辑冗余且不符合预期
修正后可运行代码
import os import requests path = "/Users/mycode/Documents/API upload/" api_endpoint = "xxxxxx" # 遍历目标目录下的所有条目 for entry in os.scandir(path): # 跳过子目录、软链接,仅处理普通文件 if entry.is_file(follow_symlinks=False): # 通过上下文管理器自动管理文件开合,避免资源泄漏 with open(entry.path, 'rb') as file_obj: upload_files = {'file': file_obj} response = requests.post(url=api_endpoint, files=upload_files) if response.status_code == 200: print(f"文件 {entry.name} 上传成功,状态码:{response.status_code}") else: print(f"文件 {entry.name} 上传失败,状态码:{response.status_code}")
关键修正说明
- 用
os.scandir()遍历目标目录下的所有条目,替代原代码错误的字符串迭代逻辑 - 增加文件类型校验,主动跳过子目录、软链接,避免尝试打开目录触发同类报错
- 用
with上下文管理器处理文件IO,文件上传完成后自动关闭,无需手动调用close方法 - 调整循环逻辑,每次循环读取单个文件构造上传请求,避免重复传输和资源浪费
- 直接通过目录条目对象的
path属性获取文件完整路径,无需多余的路径拼接、绝对路径转换操作
内容的提问来源于stack exchange,提问作者Mycode
相关产品推荐
相关产品推荐

