apppublic/aidocs/CSVData.md
2025-10-05 11:23:33 +08:00

217 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CSVData 类技术文档
`CSVData` 是一个用于读取和处理 CSV 文件的 Python 类,提供了两种读取模式:一次性加载全部数据(`read()`)和逐行迭代处理(`iterRead()`)。该类支持自定义字段名、跳过标题行和数据起始行,适用于灵活解析各种格式的 CSV 数据。
---
## 📦 模块依赖
```python
import csv
```
> 使用标准库中的 `csv` 模块进行 CSV 文件解析。
---
## 🔧 类定义
### `class CSVData(csvfile, names=None, headline=0, dataline=1)`
#### 参数说明:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `csvfile` | str | 必填 | CSV 文件路径 |
| `names` | list 或 None | `None` | 自定义字段名称列表。若提供,则忽略文件中的标题行 |
| `headline` | int | `0` | 标题行所在的行号(从 0 开始),仅在 `names``None` 时使用 |
| `dataline` | int | `1` | 实际数据开始的行号(从 0 开始) |
---
## 📚 方法说明
### 1. `__init__(self, csvfile, names=None, headline=0, dataline=1)`
初始化 CSVData 实例,设置文件路径与解析参数。
---
### 2. `read(self) -> list[dict]`
以列表形式返回所有记录,每条记录是一个字典(键为字段名,值为对应列值)。
#### 返回值:
- `list[dict]`: 包含所有数据记录的列表,例如:
```python
[
{'st_date': '2024-01-01', 'open_price': '100', ...},
{'st_date': '2024-01-02', 'open_price': '102', ...},
...
]
```
#### 工作流程:
1. 打开 CSV 文件(二进制模式 `'rb'` ⚠️ 存在潜在问题,请见下方【⚠️ 注意事项】)
2. 创建 `csv.reader` 对象
3. 若未指定 `names`,则读取第 `headline` 行作为字段名
4. 从第 `dataline` 行开始逐行构建字典记录并添加到结果列表中
5. 关闭文件并返回数据
> ✅ 适合小到中等规模的数据集。
---
### 3. `iterRead(self)`
以流式方式逐行读取 CSV 文件,并触发事件回调函数。适用于大数据文件,避免内存溢出。
#### 回调机制:
- `onBegin()`: 在开始读取前调用(当前实现为空)
- `onRecord(rec)`: 每处理一行有效数据时调用
- `onFinish()`: 成功完成读取后调用
#### 异常处理:
- 使用 `try-except` 捕获异常,确保文件关闭
- 出现错误时重新抛出异常(但变量作用域有误,请见【⚠️ Bug 提示】)
> ✅ 推荐用于大型 CSV 文件处理。
---
### 4. `onBegin(self)`
钩子方法,在迭代读取开始前被调用。默认为空实现,可由子类重写。
> 当前代码中调用了 `self.onBegin()`,但该方法未定义 —— 应为 `onReadBegin`?请见下方 Bug 分析。
---
### 5. `onRecord(self, rec)`
每读取一条有效记录时调用此方法。
#### 参数:
- `rec` (dict): 当前行数据,形如 `{字段名: 值}`
#### 默认行为:
打印当前记录(`print(rec)`
> 可继承此类并重写该方法以实现自定义逻辑(如入库、计算等)。
---
### 6. `onFinish(self)`
所有数据读取完成后调用。
#### 默认行为:
打印 `"onFinish() called"`
> 可用于资源清理或结束通知。
---
## 🖥️ 示例用法
```python
if __name__ == '__main__':
import sys
cd = CSVData(
sys.argv[1],
names=['st_date','open_price','max_price','min_price','close_price','volume','adj_price']
)
cd.iterRead()
```
### 说明:
- 从命令行传入 CSV 文件路径
- 使用自定义字段名,不依赖文件头部
- 调用 `iterRead()` 流式输出每一行数据
---
## ⚠️ 注意事项与改进建议
### ❗Bug 与潜在问题
| 问题 | 描述 | 建议修复 |
|------|------|---------|
| 1. `onBegin()` 调用错误 | 代码中调用 `self.onBegin()`,但实际定义的是 `onReadBegin()`,会导致 `AttributeError` | 将 `onReadBegin` 改名为 `onBegin`,或修正调用 |
| 2. 异常捕获语法错误 | `except exception as e:` 中 `exception` 应为 `Exception`(首字母大写) | 改为 `except Exception as e:` |
| 3. 文件打开模式冲突 | `read()` 方法使用 `'rb'` 二进制模式打开文件,但 `csv.reader` 需要文本模式 | 改为 `'r'` 并指定编码(如 `'utf-8'` |
| 4. `fd.close()` 变量作用域错误 | 在 `except` 块中调用 `fd.close()`,但 `fd` 是实例属性应写作 `self.fd` | 改为 `self.fd.close()` |
| 5. 缺少编码设置 | 未指定字符编码,可能导致中文乱码 | 添加 `encoding='utf-8'` 参数 |
---
### ✅ 推荐修改后的 `iterRead()` 示例:
```python
def iterRead(self):
self.fd = open(self.csvfile, 'r', encoding='utf-8')
try:
reader = csv.reader(self.fd)
fields = None
if self.names is not None:
fields = self.names
lno = 0
self.onBegin() # 确保方法存在
for l in reader:
if fields is None and lno == self.headline:
fields = [f for f in l]
if lno >= self.dataline:
rec = {}
for i in range(len(fields)):
rec[fields[i]] = l[i]
self.onRecord(rec)
lno += 1
self.fd.close()
self.onFinish()
except Exception as e:
self.fd.close()
raise e
```
---
## 🧩 继承与扩展建议
可通过继承 `CSVData` 类来实现更复杂的功能:
```python
class MyCSVProcessor(CSVData):
def onBegin(self):
print("开始处理数据...")
def onRecord(self, rec):
# 示例:过滤价格大于 100 的记录
if float(rec['close_price']) > 100:
print("高价值记录:", rec)
def onFinish(self):
print("数据处理完毕!")
```
---
## 📎 总结
| 特性 | 支持情况 |
|------|----------|
| 自定义字段名 | ✅ |
| 跳过标题行 | ✅ |
| 指定数据起始行 | ✅ |
| 全量读取 | ✅ (`read`) |
| 流式读取 | ✅ (`iterRead`) |
| 可扩展性 | ✅(支持回调钩子) |
| 错误处理 | ⚠️ 存在缺陷,需修复 |
| 编码支持 | ❌ 缺失,建议增加 |
---
## 📌 版本建议(改进方向)
1. 增加 `encoding` 参数,默认 `'utf-8'`
2. 修复异常捕获与方法命名
3. 使用上下文管理器 (`with open(...)`) 替代手动关闭文件
4. 添加类型注解提升可读性
5. 支持分隔符参数(如 tab、分号等
---
📘 **结论**`CSVData` 是一个结构清晰、易于扩展的 CSV 处理类,稍作修正后可用于生产环境。