使用wb模式打开文件时出现文件描述符错误及Pickle序列化问题
问题描述
我需要实现以下逻辑:从CSV文件读取数据存入字典,创建两个SymbolInfo对象存入另一个字典,将这两个字典放入元组后用Pickle序列化。
代码如下:
symbols = ["EURJPY", "EURGBP"] tup_0 = {} tup_1 = {} for symbol in symbols: sym_info_obj = symbol_info(symbol) sym_mtsim_obj = SymbolInfo(sym_info_obj) tup_0[symbol] = sym_mtsim_obj main_direc = os.path.abspath(os.getcwd()) + "\\" + "Code and Data" symbol_file = f"1M-{symbol}-1S.csv" full_file = main_direc + "\\" + symbol_file data = pd.read_csv(full_file) data["Time"] = data["Date"].astype(str) + " " + data["Timestamp"] data = data.drop(["Timestamp", "Date"], axis=1) tup_1[symbol] = data tup = (tup_0, tup_1) full_path = os.path.join(os.getcwd(), "Code and Data", "test.pkl") with open(full_path, "wb") as fh: pickle.dump(tup, fh)
注:symbol_info()是返回SymbolInfo对象的函数;.py文件、.csv文件及手动创建的.pkl文件均在同一文件夹下
执行代码时,在创建文件句柄传入pickle.dump时遇到三个问题:
- 文件或目录未找到错误
- 手动创建.pkl文件后出现无效文件描述符错误
- 使用"w"模式可打开文件,但触发类型错误,提示必须写入字符串而非字节
解决方法
1. 文件或目录未找到错误
原因:Code and Data目录可能不存在,或者手动拼接路径时因系统分隔符差异(Windows用\,Linux/macOS用/)导致路径无效。
解决:
- 用
os.makedirs提前创建目标目录,设置exist_ok=True避免重复创建报错 - 全程用
os.path.join拼接路径,自动适配系统分隔符,避免手动拼接的错误
2. 手动创建文件后无效文件描述符错误
原因:手动创建的文件可能被其他程序占用,或者权限不足,也可能路径仍有问题导致代码无法正确访问该文件。
解决:
- 不要手动创建.pkl文件,让代码在写入时自动生成
- 确保没有其他程序(比如文件管理器、编辑器)打开该.pkl文件
- 检查文件所在目录的读写权限
3. "w"模式触发类型错误
原因:pickle.dump需要写入二进制数据,而"w"模式是文本模式,只能写入字符串,类型不匹配。
解决:必须使用"wb"二进制写入模式,这是Pickle序列化的标准要求。
修改后的完整代码
import os import pickle import pandas as pd # 假设SymbolInfo和symbol_info已定义 # class SymbolInfo: # def __init__(self, info): # self.info = info # def symbol_info(symbol): # return SymbolInfo(f"info_{symbol}") symbols = ["EURJPY", "EURGBP"] tup_0 = {} tup_1 = {} # 提前创建目标目录 main_direc = os.path.join(os.getcwd(), "Code and Data") os.makedirs(main_direc, exist_ok=True) for symbol in symbols: sym_info_obj = symbol_info(symbol) sym_mtsim_obj = SymbolInfo(sym_info_obj) tup_0[symbol] = sym_mtsim_obj symbol_file = f"1M-{symbol}-1S.csv" full_file = os.path.join(main_direc, symbol_file) data = pd.read_csv(full_file) data["Time"] = data["Date"].astype(str) + " " + data["Timestamp"] data = data.drop(["Timestamp", "Date"], axis=1) tup_1[symbol] = data tup = (tup_0, tup_1) full_path = os.path.join(main_direc, "test.pkl") with open(full_path, "wb") as fh: pickle.dump(tup, fh)
内容的提问来源于stack exchange,提问作者edgar_maddocks
相关产品推荐
相关产品推荐

