# AutoReportV3 命名规范指南

## 概述

本文档定义了 AutoReportV3 项目中的标准命名规范。严格遵循这些规范确保代码的可读性、可维护性和一致性。

---

## 1. 基本命名规则

### Python 标准（PEP 8）
- **模块/文件**：`snake_case` (例：`data_processor.py`, `historical_loader.py`)
- **函数/方法**：`snake_case` (例：`load_historical_data()`, `find_common_indicators()`)
- **类**：`PascalCase` (例：`HistoricalDataLoader`, `DataMatcher`)
- **常量**：`UPPER_SNAKE_CASE` (例：`MAX_RETRIES`, `DEFAULT_TIMEOUT`)
- **私有成员**：`_leading_underscore` (例：`_internal_cache`)
- **布尔变量**：`is_`, `has_`, `can_` 前缀 (例：`is_valid`, `has_data`)

### 禁止使用的模式
- ❌ 缩写（除非在严格上下文中）：`ref_data` → ✅ `spectrum_data`
- ❌ 模糊缩写：`his_*` → ✅ `historical_*`
- ❌ 过度通用的名称：`data`, `config`, `result` （不带类型前缀）
- ❌ 单字母变量（除了循环计数器 `i`, `j`, `k`）

---

## 2. 数据生命周期命名规范

### 核心原则

数据变量应该清楚地表示其在数据流中的位置和转换阶段。

### 生命周期标记

使用以下前缀标记数据阶段：

| 前缀 | 含义 | 示例 | 说明 |
|------|------|------|------|
| `raw_` | 未处理的原始数据 | `raw_uav_data` | 直接从文件读取 |
| `processed_` | 已标准化的数据 | `processed_uav_data` | 经过清洗和标准化 |
| `matched_` | 与其他数据匹配过的子集 | `matched_spectrum_data` | 仅包含匹配的点位 |
| `training_` | 用于模型训练的数据 | `training_uav_data` | 精选用于建模 |
| `input_` | 模型/处理的输入数据 | `input_uav_data` | 作为函数参数输入 |
| `predicted_` / `output_` | 模型输出结果 | `predicted_values` | 不用 `_data` 后缀 |

### 数据类型标记

在必要时添加数据结构标记：

| 标记 | 含义 | 示例 |
|------|------|------|
| `_df` | 明确的 DataFrame | `spectrum_df`, `historical_measure_df` |
| `_array` | NumPy 数组 | `Z_array`, `grid_lon_array` |
| `_dict` / `_mapping` | 字典或映射 | `config_dict`, `indicator_mapping` |
| `_bundle` | 打包对象容器 | `historical_bundle`, `result_bundle` |
| `_results` / `_output` | 结果集合 | `analysis_results`, `model_output` |

### 数据流示例

**UAV 反演数据流：**
```
raw_uav_data（原始INDEXS.CSV + POS.TXT）
  ↓
processed_uav_data（标准化、清洗）
  ↓
matched_uav_data（与测量数据匹配的子集）
  ↓
training_uav_data（精选用于训练）
```

**光谱数据流：**
```
raw_spectrum_data（原始REFL_*.csv）
  ↓
processed_spectrum_data（标准化）
  ↓
matched_spectrum_data（与UAV采样点匹配）
  ↓
training_spectrum_data（用于建模）
```

---

## 3. 关键变量命名规范

### 容器类型变量

**数据框（DataFrame）：**
- 优先使用明确的类型前缀：`spectrum_df`, `measure_df`
- 或包含生命周期标记：`processed_uav_data`, `matched_spectrum_data`
- ❌ 避免：`data`, `df`, `current_data`

**字典/配置：**
- 明确说明用途：`config_dict`, `company_info`, `indicator_mapping`
- 布尔字典：`is_valid_dict`, `has_column_dict`
- ❌ 避免：`data`, `config`, `dict`

**列表/集合：**
- 使用复数形式：`indicators`, `values`, `column_names`
- 明确说明内容：`water_quality_grades`, `indicator_units`
- ❌ 避免：`item_list`, `data_list`, `results`

### 参数命名规范

**函数参数必须具有描述性：**

```python
# ❌ 不好
def process(data, config, options):
    pass

# ✅ 好
def process(
    report_data: ReportData,
    processing_config: ProcessingConfig,
    output_options: Dict[str, Any]
) -> ProcessedDataSet:
    pass
```

**长参数列表（>4）应考虑使用参数对象：**

```python
# ❌ 不好：参数列表过长
def analyze_data(
    uav_data, measure_data, spectrum_data,
    has_measured_data, visualization_mode,
    satellite_bounds, config_service
):
    pass

# ✅ 好：使用参数对象
@dataclass
class AnalysisParams:
    uav_data: pd.DataFrame
    measure_data: pd.DataFrame
    spectrum_data: pd.DataFrame
    has_measured_data: bool
    visualization_mode: str
    satellite_bounds: Tuple[float, float, float, float]
    config_service: ConfigurationService

def analyze_data(params: AnalysisParams) -> AnalysisResult:
    pass
```

---

## 4. 特殊情况说明

### 坐标数据

- **标准命名**：`longitude`, `latitude`
- ❌ 避免缩写：`lon`, `lat`, `lng`
- 在容器中：`coord_lon`, `coord_lat`
- 网格数据：`grid_lon`, `grid_lat`

### 返回值类型

**单个返回值：** 使用清晰的名称
```python
def get_indicator_unit(indicator: str) -> str:
    """获取指标单位"""
    return unit_mapping.get(indicator, "")
```

**多返回值：** 使用 NamedTuple 或 TypedDict
```python
from typing import NamedTuple

class InterpolationResult(NamedTuple):
    Z: np.ndarray
    grid_lon: np.ndarray
    grid_lat: np.ndarray
    mask: np.ndarray
    boundary: Optional[np.ndarray]

def perform_interpolation(...) -> InterpolationResult:
    return InterpolationResult(Z, grid_lon, grid_lat, mask, boundary)
```

### 中间变量

**转换过程中的中间值：** 清楚标记处理阶段
```python
# 好的做法
raw_data = load_data(file_path)
cleaned_data = remove_nulls(raw_data)
validated_data = validate_ranges(cleaned_data)
normalized_data = normalize_values(validated_data)

# ❌ 避免：data1, data2, data3 这样的通用名称
```

---

## 5. 代码审查检查清单

在提交代码时，检查以下命名相关的项目：

### ✅ 变量命名
- [ ] 所有变量使用 `snake_case`
- [ ] 没有不明确的缩写（`ref_data`, `his_*` 等）
- [ ] 数据变量包含生命周期标记（`raw_`, `processed_`, `matched_`, `training_`）
- [ ] 布尔变量使用 `is_`, `has_`, `can_` 前缀
- [ ] DataFrame 变量包含 `_df` 后缀或明确的类型名

### ✅ 参数命名
- [ ] 函数参数使用描述性名称，不是 `data`, `config`, `options`
- [ ] 参数名称清楚表示其用途和类型
- [ ] 类型注解与参数名称一致

### ✅ 返回值
- [ ] 复杂返回值使用 NamedTuple 或 TypedDict
- [ ] 返回值字段名清楚、有意义
- [ ] 文档说明返回值的内容

### ✅ 容器和集合
- [ ] 字典键名有意义（`indicator_mapping` 而不是 `data_dict`）
- [ ] 列表/集合变量使用复数形式（`indicators`, `values`）
- [ ] 数据流清晰追踪（可以跟踪 raw → processed → matched 的转变）

### ✅ 禁用的模式
- [ ] 不使用 `ref_data`（应该是 `spectrum_data`）
- [ ] 不使用模糊的 `merged_data`（应该是 `processed_uav_data` 等）
- [ ] 不使用 `his_*` 缩写（应该是 `historical_*`）
- [ ] 不使用过于通用的 `data`, `config`, `result` 作为独立变量

---

## 6. 迁移指南

### 现有代码迁移

对于现有不符合规范的变量名，按照以下优先级逐步迁移：

**高优先级（1-2 周内）：**
- `ref_data` → `spectrum_data` （歧义最高）
- `his_instance` → `historical_bundle` （已完成 ✅）
- `common_indicators` → `intersection_indicators` （已完成 ✅）

**中优先级（2-3 周内）：**
- `merged_data` → context-specific names（`processed_uav_data` / `input_uav_data` / `training_uav_data`）
- `modeling_*` prefix → `training_*` prefix
- 复杂返回值转换为 NamedTuple/TypedDict

**低优先级（可选，3 周以后）：**
- `config` 字典迁移到 `ExecutionConfig` TypedModel
- 通用参数名 `data`, `config`, `result` 的系统性重命名

### 向后兼容性

在迁移过程中，使用别名保持向后兼容性：

```python
# 过渡期：保留旧名称作为别名
@property
def ref_data(self) -> pd.DataFrame:
    """向后兼容：使用 spectrum_data 代替"""
    return self.spectrum_data
```

---

## 7. 特殊约定

### 地理信息相关

- **边界**：`bounds` 或 `geo_bounds` （4 元组：min_lon, min_lat, max_lon, max_lat）
- **坐标**：`longitude`, `latitude`
- **距离**：`distance`, `distance_meters`, `distance_km`

### 时间相关

- **时间戳**：`timestamp`, `created_at`, `updated_at`
- **时间段**：`duration`, `duration_seconds`, `time_range`
- **日期**：`date`, `start_date`, `end_date`

### 指标相关

- **指标列表**：`indicators`
- **指标值**：`indicator_value`, `value` （在指标上下文中）
- **指标单位**：`indicator_unit`, `unit`

---

## 8. 常见问题

### Q: 什么时候使用 `_df` 后缀？

**A:** 当在同一作用域中混合不同类型的数据，需要明确区分 DataFrame 时才使用。例如：
```python
# 有必要：混合了不同类型
spectrum_df = pd.DataFrame(...)
spectrum_array = spectrum_df.values  # NumPy 数组
spectrum_dict = spectrum_df.to_dict()  # 字典

# 没必要：上下文已清晰
spectrum_data = pd.read_csv(...)  # DataFrame 类型清晰
```

### Q: 缩写可以用吗？

**A:** 仅在严格的、明显的上下文中使用。例如：
```python
# ✅ 可以：循环计数器的通用缩写
for i in range(len(data)):
    pass

# ✅ 可以：众所周知的领域缩写（文档中已定义）
pH = 7.0  # 水质 pH 值（领域常用）
DO = dissolved_oxygen  # 溶解氧（行业标准）

# ❌ 不可以：不标准的、容易混淆的缩写
ref_data  # 不清楚是 reference 还是 reflectance
his_data  # 不标准
```

### Q: 如何处理与外部库的命名冲突？

**A:** 使用别名或前缀区分：
```python
# 如果外部库使用了冲突的名称
import external_lib as ext
ext_config = ext.config
our_config = our_configuration

# 或使用更明确的名称
import external_lib
external_config = external_lib.config
internal_config = internal_configuration
```

---

## 9. 版本历史

| 版本 | 日期 | 更新内容 |
|------|------|---------|
| 1.0 | 2025-12-04 | 初版：建立基础命名规范，包括数据生命周期规范 |

---

## 10. 相关文档

- [VARIABLE_NAMING_OPTIMIZATION_PLAN.md](../VARIABLE_NAMING_OPTIMIZATION_PLAN.md) - 详细的优化计划和实施路线图
- [Python 项目开发规范](../../Python项目开发规范.md) - 全面的代码质量标准
- PEP 8 - Python 官方风格指南：https://www.python.org/dev/peps/pep-0008/

---

**最后更新**：2025-12-04
**维护者**：AutoReportV3 开发团队
**状态**：✅ 活跃维护
