474 lines
14 KiB
Markdown
474 lines
14 KiB
Markdown
# 代码风格指南
|
||
|
||
## 1. 命名风格
|
||
|
||
### 1.1 类名
|
||
- **风格**:帕斯卡命名法(PascalCase)
|
||
- **规则**:首字母大写,每个单词首字母也大写
|
||
- **示例**:
|
||
```python
|
||
class StringLoader:
|
||
pass
|
||
|
||
class FlaskAppWrapper:
|
||
pass
|
||
|
||
class ParameterValidator:
|
||
pass
|
||
```
|
||
|
||
### 1.2 函数名
|
||
- **风格**:驼峰命名法(CamelCase)
|
||
- **规则**:首字母大写,每个单词首字母也大写
|
||
- **示例**:
|
||
```python
|
||
def RegisterBlueprint(self, name: str, blueprint: Any, allow_ignore: str = "") -> None:
|
||
pass
|
||
|
||
def GetBlueprint(self, name: str) -> Tuple[Any, str]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def _is_empty_value(value: Any) -> bool:
|
||
pass
|
||
```
|
||
|
||
### 1.3 变量名
|
||
- **全局变量**:
|
||
- **风格**:全大写字母,下划线分隔(UPPER_SNAKE_CASE)
|
||
- **示例**:
|
||
```python
|
||
CPU_CORES = os.cpu_count() or 4
|
||
MAX_COROUTINES = CPU_CORES * 50
|
||
LOG_CONFIG = {}
|
||
```
|
||
|
||
- **实例变量**:
|
||
- **风格**:驼峰命名法(CamelCase)
|
||
- **示例**:
|
||
```python
|
||
self.App = App
|
||
self.Limiter = Limiter
|
||
self.Blueprints: Dict[str, Dict[str, Any]] = {}
|
||
```
|
||
|
||
- **局部变量**:
|
||
- **风格**:蛇形命名法(snake_case)
|
||
- **示例**:
|
||
```python
|
||
code_str = code
|
||
target_type = 'str'
|
||
matched_dirs = [dir for dir in handlers if normalized_route.startswith(dir)]
|
||
```
|
||
|
||
### 1.4 常量
|
||
- **风格**:全大写字母,下划线分隔(UPPER_SNAKE_CASE)
|
||
- **示例**:
|
||
```python
|
||
DEFAULT_TIMESTAMP_STR_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||
TIMESTAMP_STR_PATTERNS = {
|
||
"%Y-%m-%d %H:%M:%S": re.compile(r'^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$'),
|
||
# ...
|
||
}
|
||
```
|
||
|
||
### 1.5 类型别名
|
||
- **风格**:帕斯卡命名法(PascalCase)
|
||
- **示例**:
|
||
```python
|
||
ApiMetadata = Dict[str, Any]
|
||
RouteHandler = Callable[..., Any]
|
||
PermissionChecker = Callable[[int, List[Any]], bool]
|
||
```
|
||
|
||
### 1.6 文件名
|
||
- **风格**:蛇形命名法(snake_case)或帕斯卡命名法(PascalCase)
|
||
- **示例**:
|
||
- `FileSystemRoute.py`(帕斯卡命名法)
|
||
- `config.py`(蛇形命名法)
|
||
|
||
## 2. 写作风格
|
||
|
||
### 2.1 代码组织
|
||
- **模块化**:使用类和函数进行模块化组织
|
||
- **文件结构**:按功能划分文件和目录
|
||
- **代码层次**:逻辑清晰,层次分明
|
||
|
||
### 2.2 注释
|
||
- **文档字符串(Docstring)**:
|
||
- 用于类和函数的说明
|
||
- 描述功能、参数和返回值
|
||
- **示例**:
|
||
```python
|
||
@staticmethod
|
||
def _is_empty_value(value: Any) -> bool:
|
||
"""判断值是否为空(空字符串、空列表、空字典、None)"""
|
||
# 实现...
|
||
```
|
||
|
||
- **单行注释**:
|
||
- 用于解释复杂逻辑或重要变量
|
||
- 放在代码行上方或右侧
|
||
- **示例**:
|
||
```python
|
||
# 补充缺失的时区定义(确保代码可运行)
|
||
Timezone_UTFA8 = datetime.now().astimezone().tzinfo
|
||
|
||
# 空字符串仅在目标类型为str时返回,其他类型直接抛出错误
|
||
if isinstance(value, str) and value.strip() == "":
|
||
if target_type != 'str':
|
||
raise ValueError(f"空字符串无法转换为 {target_type} 类型")
|
||
return ""
|
||
```
|
||
|
||
### 2.3 缩进和空格
|
||
- **缩进**:使用4个空格进行缩进
|
||
- **空格**:
|
||
- 操作符两侧使用空格
|
||
- 逗号后使用空格
|
||
- 函数参数等号两侧使用空格
|
||
- **示例**:
|
||
```python
|
||
if value is None:
|
||
return True
|
||
|
||
def _convert_value(value: str, target_type: str, **kwargs) -> Any:
|
||
# 实现...
|
||
```
|
||
|
||
### 2.4 空行
|
||
- **类和函数之间**:使用2个空行分隔
|
||
- **函数内部逻辑块**:使用1个空行分隔
|
||
- **示例**:
|
||
```python
|
||
class StringLoader:
|
||
# 实现...
|
||
|
||
|
||
class FlaskAppWrapper:
|
||
# 实现...
|
||
|
||
def RegisterBlueprint(self, name: str, blueprint: Any, allow_ignore: str = "") -> None:
|
||
# 实现...
|
||
|
||
# 空行分隔逻辑块
|
||
if not directory.startswith("/"):
|
||
directory = f"/{directory}"
|
||
if not directory.endswith("/"):
|
||
directory = f"{directory}/"
|
||
```
|
||
|
||
### 2.5 类型提示
|
||
- **使用Python 3的类型提示功能**
|
||
- **函数参数和返回值都应有明确的类型提示**
|
||
- **示例**:
|
||
```python
|
||
def _convert_value(value: str, target_type: str, **kwargs) -> Any:
|
||
# 实现...
|
||
|
||
def GetBlueprint(self, name: str) -> Tuple[Any, str]:
|
||
# 实现...
|
||
```
|
||
|
||
### 2.6 异常处理
|
||
- **使用try-except块进行异常捕获和处理**
|
||
- **明确指定异常类型**
|
||
- **示例**:
|
||
```python
|
||
try:
|
||
# 实现...
|
||
except ValueError as e:
|
||
raise ValueError(f"UUID格式错误: {str(e)}") from e
|
||
except (TypeError, ValueError) as e:
|
||
print(traceback.format_exc())
|
||
raise ValueError(f"类型转换失败(预期{target_type}): {str(e)}") from e
|
||
```
|
||
|
||
### 2.7 代码可读性
|
||
- **使用有意义的变量名和函数名**
|
||
- **逻辑清晰,层次分明**
|
||
- **适当使用空格和换行,提高代码可读性**
|
||
- **避免过长的代码行(建议不超过100个字符)**
|
||
|
||
## 3. 最佳实践
|
||
|
||
### 3.1 命名规范一致性
|
||
- **保持命名风格一致**:在整个项目中使用相同的命名规范
|
||
- **避免混用不同的命名风格**
|
||
|
||
### 3.2 代码简洁性
|
||
- **避免冗余代码**
|
||
- **使用Python的内置功能和标准库**
|
||
- **保持函数和类的职责单一**
|
||
|
||
### 3.3 错误处理
|
||
- **全面的错误处理**:捕获可能的异常并进行适当处理
|
||
- **提供清晰的错误信息**:错误信息应包含足够的上下文信息
|
||
|
||
### 3.4 性能考虑
|
||
- **避免不必要的计算**
|
||
- **合理使用缓存**
|
||
- **优化关键路径的代码**
|
||
|
||
### 3.5 可维护性
|
||
- **良好的代码结构**:模块化设计,层次清晰
|
||
- **完善的文档**:代码应有适当的注释和文档
|
||
- **可测试性**:代码应易于测试
|
||
|
||
## 4. TempLateAPI 代码风格
|
||
|
||
### 4.1 目录结构
|
||
|
||
TempLateAPI 目录采用模块化结构,按照功能和业务领域组织 API 文件:
|
||
|
||
```
|
||
TempLateAPI/
|
||
├── 3CRB/ # 3CRB 模块
|
||
│ ├── API/ # API 定义
|
||
│ │ ├── Enterprise/ # 企业相关 API
|
||
│ │ ├── StoredValue/ # 储值相关 API
|
||
│ │ └── wallet.api # 钱包 API
|
||
│ └── Errors/ # 错误处理 API
|
||
├── CCGO/ # CCGO 模块
|
||
├── GERP/ # GERP 模块
|
||
│ ├── API/ # API 定义
|
||
│ │ ├── AccountActivation/ # 账户激活
|
||
│ │ ├── Backpack/ # 背包管理
|
||
│ │ ├── Department/ # 部门管理
|
||
│ │ └── ... # 其他功能
|
||
│ └── Errors/ # 错误处理 API
|
||
├── Invite/ # 邀请模块
|
||
├── SVE/ # SVE 模块
|
||
├── UGM/ # 用户管理模块
|
||
│ ├── Auth/ # 认证相关 API
|
||
│ ├── Errors/ # 错误处理 API
|
||
│ ├── Modify/ # 修改相关 API
|
||
│ └── Query/ # 查询相关 API
|
||
└── Verifox/ # Verifox 模块
|
||
```
|
||
|
||
### 4.2 文件命名规范
|
||
|
||
- **API 文件**:使用驼峰命名法(CamelCase),如 `Login.api`、`GetEnterprise.api`
|
||
- **目录名称**:使用驼峰命名法或 Pascal 命名法,如 `Enterprise`、`StoredValue`
|
||
- **模块名称**:使用大写字母,如 `3CRB`、`UGM`、`GERP`
|
||
|
||
### 4.3 代码风格
|
||
|
||
#### 4.3.1 导入语句
|
||
|
||
- **标准导入**:从 `PDAPI` 导入所有内容
|
||
|
||
```python
|
||
from PDAPI import *
|
||
```
|
||
|
||
#### 4.3.2 元数据定义
|
||
|
||
- **元数据结构**:使用 `__metadata__` 字典定义 API 的属性
|
||
- **键名风格**:使用驼峰命名法
|
||
|
||
```python
|
||
__metadata__ = {
|
||
"methods": ["GET", "POST"],
|
||
"blueprint": "UGM",
|
||
"permission": 1.0,
|
||
"attributes": [],
|
||
"rate_limit": "1 per seconds",
|
||
"form": [
|
||
{"Name": "UserPassWord", "Type": "str", "MaxLen": 256}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 4.3.3 处理函数
|
||
|
||
- **函数定义**:使用 `HandleRequest()` 函数处理请求
|
||
- **函数命名**:驼峰命名法
|
||
|
||
```python
|
||
def HandleRequest():
|
||
# 处理逻辑
|
||
return response
|
||
```
|
||
|
||
#### 4.3.4 变量命名
|
||
|
||
- **局部变量**:使用驼峰命名法,如 `UserPassWord`、`EnterpriseList`
|
||
- **全局变量**:使用驼峰命名法,如 `CMEBalances`、`ELTUser`
|
||
|
||
```python
|
||
UserPassWord = flask.request.form.get("UserPassWord")
|
||
EnterpriseList = []
|
||
```
|
||
|
||
#### 4.3.5 函数调用
|
||
|
||
- **函数命名**:使用驼峰命名法,如 `GetUserDataByUserJobNumber`、`CheckPassword`
|
||
- **参数传递**:直接传递参数,没有特殊格式要求
|
||
|
||
```python
|
||
if not NonLegalChar(UserName): return flask.redirect(flask.url_for("MainLoginHTML", msg = "该用户名称存在非法字符"))
|
||
if not (_ := GetUserDataByUserJobNumber(Get16toBytes(UserJobNumber))): return flask.redirect(flask.url_for("MainLoginHTML", msg = "用户不存在"))
|
||
```
|
||
|
||
#### 4.3.6 控制流
|
||
|
||
- **条件语句**:使用标准的 `if-elif-else` 结构
|
||
- **循环语句**:使用标准的 `for` 循环
|
||
- **错误处理**:通常通过条件判断和重定向处理错误
|
||
|
||
```python
|
||
if flask.request.method == "GET": return flask.redirect(flask.url_for("MainLoginHTML"))
|
||
if not form.validate_on_submit(): return flask.redirect(flask.url_for("MainLoginHTML", msg = list(form.errors.values())[0][0]))
|
||
|
||
for i in Enterprise.query.filter(Enterprise.EnterpriseUUID.in_(tuple(i.EnterpriseUUID for i in r))).all():
|
||
# 处理逻辑
|
||
```
|
||
|
||
#### 4.3.7 缩进和空格
|
||
|
||
- **缩进**:使用 4 个空格进行缩进
|
||
- **空格**:操作符两侧、逗号后使用空格
|
||
- **空行**:模块导入和元数据定义之间、元数据定义和处理函数之间使用空行
|
||
|
||
#### 4.3.8 注释
|
||
|
||
- **注释风格**:注释较少,但代码逻辑清晰
|
||
- **文档字符串**:通常不使用文档字符串
|
||
|
||
#### 4.3.9 响应处理
|
||
|
||
- **重定向**:使用 `flask.redirect` 处理重定向
|
||
- **JSON 响应**:直接返回字典,会被自动转换为 JSON
|
||
- **错误处理**:通常通过重定向或返回错误信息实现
|
||
|
||
```python
|
||
# 重定向示例
|
||
if flask.request.method == "GET": return flask.redirect(flask.url_for("MainLoginHTML"))
|
||
|
||
# JSON 响应示例
|
||
return {"status": 0, "data": EnterpriseList}
|
||
```
|
||
|
||
### 4.4 API 处理流程
|
||
|
||
#### 4.4.1 典型流程
|
||
|
||
1. **请求方法检查**:如 GET 请求可能重定向到 HTML 页面
|
||
2. **参数获取**:获取表单数据或 URL 参数
|
||
3. **参数验证**:验证参数合法性
|
||
4. **权限检查**:检查用户权限
|
||
5. **业务逻辑执行**:执行核心业务逻辑
|
||
6. **数据库操作**:处理数据库查询和修改
|
||
7. **响应返回**:返回重定向或 JSON 数据
|
||
|
||
#### 4.4.2 示例流程(Login.api)
|
||
|
||
1. 检查请求方法,GET 请求重定向到登录页面
|
||
2. 验证表单数据
|
||
3. 获取用户名和密码
|
||
4. 检查用户名合法性
|
||
5. 根据工号或用户名获取用户数据
|
||
6. 验证密码
|
||
7. 检查账户许可证状态
|
||
8. 创建会话令牌
|
||
9. 更新用户最后登录时间
|
||
10. 提交数据库操作
|
||
11. 设置 cookie 并重定向到主页面
|
||
|
||
#### 4.4.3 示例流程(GetEnterprise.api)
|
||
|
||
1. 获取用户信息
|
||
2. 获取用户的企业列表
|
||
3. 查询每个企业的详细信息
|
||
4. 构建企业信息列表
|
||
5. 返回企业信息 JSON 数据
|
||
|
||
### 4.5 特殊特点
|
||
|
||
#### 4.5.1 全局变量使用
|
||
|
||
- 使用 `flask.g` 存储全局变量,如 `flask.g.ELTUser`
|
||
|
||
#### 4.5.2 数据库操作
|
||
|
||
- 使用 SQLAlchemy ORM 进行数据库操作
|
||
- 通常使用 `try-except` 块处理数据库提交错误
|
||
|
||
#### 4.5.3 字节转换
|
||
|
||
- 频繁使用 `GetBytesTo16` 和 `Get16toBytes` 等函数处理字节和字符串转换
|
||
|
||
#### 4.5.4 重定向处理
|
||
|
||
- 频繁使用 `flask.redirect` 和 `flask.url_for` 处理页面跳转
|
||
|
||
#### 4.5.5 错误处理
|
||
|
||
- 错误处理通常通过重定向或返回错误信息实现,较少使用异常处理
|
||
|
||
### 4.6 代码风格总结
|
||
|
||
#### 4.6.1 优点
|
||
|
||
1. **代码结构清晰**:API 文件独立,目录结构合理
|
||
2. **命名规范统一**:变量和函数命名一致,使用驼峰命名法
|
||
3. **代码简洁**:直接处理业务逻辑,没有冗余代码
|
||
4. **逻辑清晰**:API 处理流程明确,易于理解
|
||
5. **模块化**:按照功能模块组织代码,便于维护
|
||
|
||
#### 4.6.2 改进空间
|
||
|
||
1. **注释不足**:代码注释较少,可能影响后期维护
|
||
2. **错误处理**:错误处理可以更加规范,使用异常处理机制
|
||
3. **代码复用**:有些重复代码可以提取为公共函数
|
||
4. **类型提示**:可以添加类型提示,提高代码可读性
|
||
5. **文档**:可以添加 API 文档,便于其他开发者理解
|
||
|
||
#### 4.6.3 最佳实践
|
||
|
||
1. **保持命名规范**:继续使用驼峰命名法,保持一致性
|
||
2. **添加注释**:为复杂逻辑添加注释,提高代码可读性
|
||
3. **规范错误处理**:使用统一的错误处理机制
|
||
4. **代码复用**:提取公共函数,减少代码重复
|
||
5. **添加类型提示**:使用 Python 3 的类型提示功能
|
||
6. **添加 API 文档**:为 API 添加文档,便于其他开发者理解
|
||
7. **测试覆盖**:为 API 添加单元测试,确保功能正常
|
||
|
||
## 5. 总结
|
||
|
||
本项目的代码风格具有以下特点:
|
||
|
||
1. **命名规范统一**:
|
||
- 类名使用帕斯卡命名法
|
||
- 函数名使用驼峰命名法
|
||
- 全局变量和常量使用全大写字母,下划线分隔
|
||
- 局部变量使用蛇形命名法
|
||
|
||
2. **代码风格清晰**:
|
||
- 使用4个空格缩进
|
||
- 适当的空行分隔
|
||
- 完善的注释和文档字符串
|
||
- 明确的类型提示
|
||
|
||
3. **代码质量高**:
|
||
- 模块化设计
|
||
- 异常处理完善
|
||
- 代码可读性强
|
||
- 性能考虑充分
|
||
|
||
4. **最佳实践**:
|
||
- 命名规范一致性
|
||
- 代码简洁性
|
||
- 错误处理全面
|
||
- 性能优化
|
||
- 可维护性强
|
||
|
||
5. **TempLateAPI 特色**:
|
||
- 模块化目录结构
|
||
- 统一的 API 处理流程
|
||
- 简洁的代码风格
|
||
- 清晰的响应处理
|
||
|
||
遵循这些代码风格和命名规范,有助于提高代码的可读性、可维护性和可扩展性,同时也便于团队协作和代码审查。 |