219 lines
5.2 KiB
Markdown
219 lines
5.2 KiB
Markdown
# CSVData 模块技术文档
|
||
|
||
```markdown
|
||
# CSVData 技术文档
|
||
|
||
## 简介
|
||
|
||
`CSVData` 是一个轻量级的 Python 模块,用于读取和解析 CSV 文件。它支持自定义编码格式和分隔符,并将每行数据以字典形式返回,字段名为键,对应值为内容。该模块避免了标准库 `csv` 模块的部分限制,提供了更灵活的控制能力。
|
||
|
||
> ⚠️ 注意:本模块兼容 Python 2,若在 Python 3 中使用需进行适当调整(如 `next()` 方法名冲突)。
|
||
|
||
---
|
||
|
||
## 模块依赖
|
||
|
||
- `codecs`: 用于处理文件编码。
|
||
- `csv`: (导入但未实际使用,可移除)
|
||
|
||
---
|
||
|
||
## 类说明
|
||
|
||
### `Reader` 类
|
||
|
||
逐行读取文本文件并按指定分隔符分割字段。
|
||
|
||
#### 构造函数:`__init__(self, f, delimiter)`
|
||
|
||
| 参数 | 类型 | 描述 |
|
||
|-----------|------------|--------------------------|
|
||
| `f` | file object | 已打开的文件对象 |
|
||
| `delimiter` | str | 字段之间的分隔符,默认为 `,` |
|
||
|
||
**属性:**
|
||
- `self.f`: 文件对象
|
||
- `self.delimiter`: 分隔符
|
||
- `self.line`: 当前行号(从 1 开始计数)
|
||
|
||
---
|
||
|
||
#### 方法:`__iter__()`
|
||
|
||
使 `Reader` 成为可迭代对象。
|
||
|
||
**返回值:**
|
||
- 返回自身实例,支持迭代协议。
|
||
|
||
---
|
||
|
||
#### 方法:`next()`
|
||
|
||
读取下一行并解析为字段列表。
|
||
|
||
**逻辑流程:**
|
||
1. 调用 `readline()` 读取一行。
|
||
2. 若为空字符串(EOF),抛出 `StopIteration`。
|
||
3. 去除末尾的换行符(`\n` 或 `\r`)。
|
||
4. 使用 `delimiter` 分割字符串。
|
||
5. 将空字符串转换为 `None`。
|
||
6. 行号递增。
|
||
7. 返回字段列表。
|
||
|
||
**返回值:**
|
||
- `list`: 字段值列表,空字段替换为 `None`。
|
||
|
||
**异常:**
|
||
- `StopIteration`: 文件结束时触发。
|
||
|
||
---
|
||
|
||
### `CSVData` 类
|
||
|
||
封装 CSV 文件的高级读取器,自动识别首行为字段名(header),后续行为记录。
|
||
|
||
#### 构造函数:`__init__(filename, coding='utf8', delimiter=',')`
|
||
|
||
| 参数 | 类型 | 默认值 | 描述 |
|
||
|-------------|--------|-----------|----------------------------|
|
||
| `filename` | str | - | CSV 文件路径 |
|
||
| `coding` | str | `'utf8'` | 文件编码方式 |
|
||
| `delimiter` | str | `','` | 字段分隔符 |
|
||
|
||
**内部初始化动作:**
|
||
- 使用 `codecs.open` 打开文件,确保正确解码。
|
||
- 创建 `Reader` 实例。
|
||
- 读取第一行作为字段名(`self.fields`)。
|
||
|
||
**属性:**
|
||
- `self.filename`: 文件路径
|
||
- `self.coding`: 编码格式
|
||
- `self.f`: 打开的文件对象
|
||
- `self.reader`: `Reader` 实例
|
||
- `self.fields`: 字段名列表(来自第一行)
|
||
|
||
---
|
||
|
||
#### 方法:`__del__()`
|
||
|
||
析构函数,确保文件被关闭。
|
||
|
||
> ❗ 提示:建议显式管理资源(如使用上下文管理器),因为 `__del__` 不一定及时调用。
|
||
|
||
---
|
||
|
||
#### 方法:`__iter__()`
|
||
|
||
使 `CSVData` 成为可迭代对象。
|
||
|
||
**返回值:**
|
||
- 返回自身实例。
|
||
|
||
---
|
||
|
||
#### 方法:`next()`
|
||
|
||
读取下一条记录并构造成字典。
|
||
|
||
**逻辑流程:**
|
||
1. 调用 `self.reader.next()` 获取字段值列表 `r`。
|
||
2. 校验字段数量是否与 `self.fields` 一致:
|
||
- 若不一致,打印警告信息并终止迭代。
|
||
3. 构建字典 `d`,键为字段名,值为对应列值。
|
||
4. 返回字典。
|
||
|
||
**返回值:**
|
||
- `dict`: `{字段名: 值}` 的映射。
|
||
|
||
**异常处理:**
|
||
- 捕获所有异常并统一抛出 `StopIteration`,导致迭代终止。
|
||
|
||
> ⚠️ 风险:过于宽泛的 `except:` 可能掩盖真实错误。
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
```python
|
||
from csvdata import CSVData
|
||
|
||
# 读取 UTF-8 编码的 CSV 文件
|
||
cd = CSVData('data.csv')
|
||
|
||
for row in cd:
|
||
print(row)
|
||
```
|
||
|
||
输出示例:
|
||
```python
|
||
{'name': 'Alice', 'age': '30', 'city': 'Beijing'}
|
||
{'name': 'Bob', 'age': '25', 'city': 'Shanghai'}
|
||
```
|
||
|
||
支持自定义分隔符:
|
||
```python
|
||
cd = CSVData('data.tsv', delimiter='\t')
|
||
```
|
||
|
||
---
|
||
|
||
## 主程序入口(命令行运行)
|
||
|
||
当模块直接执行时,接受一个命令行参数(文件路径),并打印所有记录。
|
||
|
||
```bash
|
||
python csvdata.py example.csv
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项与改进建议
|
||
|
||
### 兼容性问题(Python 2 vs Python 3)
|
||
- 在 Python 3 中,`next()` 应重命名为 `__next__()`。
|
||
- 推荐修改如下:
|
||
```python
|
||
def __next__(self):
|
||
return self.next()
|
||
```
|
||
|
||
### 安全性与健壮性
|
||
- `except:` 过于宽泛,应捕获具体异常(如 `StopIteration`、`IOError`)。
|
||
- `d.update(...)` 使用列表推导副作用,风格不佳,建议改为显式循环。
|
||
|
||
### 改进建议代码片段
|
||
|
||
```python
|
||
# 替代原字典构建方式
|
||
d = {self.fields[i]: r[i] for i in range(len(self.fields))}
|
||
```
|
||
|
||
或:
|
||
|
||
```python
|
||
d = dict(zip(self.fields, r))
|
||
```
|
||
|
||
### 推荐添加上下文管理器支持
|
||
|
||
```python
|
||
def __enter__(self):
|
||
return self
|
||
|
||
def __exit__(self, *args):
|
||
self.f.close()
|
||
```
|
||
|
||
使用方式:
|
||
```python
|
||
with CSVData('data.csv') as cd:
|
||
for row in cd:
|
||
print(row)
|
||
```
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
`CSVData` 提供了一个简洁、可控的 CSV 解析方案,适用于需要精细控制解析过程的场景。尽管存在一些现代 Python 开发中的反模式,但通过简单重构即可提升其稳定性与兼容性。
|
||
``` |