Python规范编码案例如何实现?

访客 python案例 2

本文目录导读:

  1. 命名规范
  2. 代码布局
  3. 文档字符串规范
  4. 类型提示
  5. 异常处理规范
  6. 上下文管理器
  7. 日志记录规范
  8. 完整项目结构示例

我来为你详细介绍Python规范编码的实践案例,从基础规范到高级模式。

命名规范

# 错误的命名方式
x = "张三"  # 无意义的变量名
def func(a, b):  # 非描述性函数名
    pass
# 正确的命名方式
user_name = "张三"
student_count = 100
def calculate_average(scores_list):
    pass
# 类名使用驼峰命名法
class UserAccount:
    pass
# 常量使用全大写
MAX_LOGIN_ATTEMPTS = 3
API_BASE_URL = "https://api.example.com"

代码布局

# 标准文件结构示例
"""
模块功能说明:
这个模块处理用户认证相关的功能
"""
import os
import sys
from datetime import datetime
# 第三方库导入
import requests
from flask import Flask, request
# 本地应用导入
from models import User
from utils import validate_email
class UserAuthentication:
    """用户认证类"""
    def __init__(self, app: Flask):
        self.app = app
        self.secret_key = os.getenv("SECRET_KEY")
    def login(self, username: str, password: str) -> dict:
        """
        用户登录方法
        Args:
            username: 用户名
            password: 密码
        Returns:
            dict: 包含登录结果和用户信息的字典
        Raises:
            ValueError: 当用户名或密码无效时
        """
        if not username or not password:
            raise ValueError("用户名和密码不能为空")
        # 登录逻辑
        result = {
            "success": True,
            "token": self._generate_token(username)
        }
        return result
    def _generate_token(self, username: str) -> str:
        """生成认证令牌(私有方法)"""
        # 令牌生成逻辑
        pass
# 使用示例
auth = UserAuthentication(app)
# 每个运算符两边都要有空格
result = auth.login(username="admin", password="123456")

文档字符串规范

def process_user_data(user_id: int, data: dict) -> dict:
    """
    处理用户数据的函数
    详细说明函数的功能、参数和返回值。
    这里可以写更详细的说明,包括算法原理等。
    Args:
        user_id (int): 用户的唯一标识符
        data (dict): 包含用户数据的字典,格式如下:
            {
                "name": str,
                "age": int,
                "email": str
            }
    Returns:
        dict: 处理后的用户数据,包含:
            - user_id: 用户ID
            - processed_name: 处理后的用户名
            - processed_age: 处理后年龄
    Raises:
        ValueError: 当user_id无效或data格式错误时
        TypeError: 当数据类型不匹配时
    Examples:
        >>> process_user_data(1, {"name": "张三", "age": 25})
        {'user_id': 1, 'processed_name': '张三', 'processed_age': 25}
    """
    if not isinstance(user_id, int) or user_id <= 0:
        raise ValueError("user_id必须为正整数")
    if not isinstance(data, dict):
        raise TypeError("data必须是字典类型")
    # 数据处理逻辑
    processed_data = {
        "user_id": user_id,
        "processed_name": data.get("name", ""),
        "processed_age": data.get("age", 0)
    }
    return processed_data

类型提示

from typing import List, Dict, Optional, Union, Tuple
class DataProcessor:
    """数据处理器"""
    def __init__(self, config: dict):
        self.config = config
        self.processed_data: List[dict] = []
    def validate_data(self, data: Union[str, bytes, int]) -> bool:
        """验证数据格式"""
        if isinstance(data, (str, bytes)):
            return len(data) > 0
        elif isinstance(data, (int, float)):
            return data >= 0
        return False
    def process_batch(self, 
                      items: List[dict], 
                      batch_size: Optional[int] = None) -> List[dict]:
        """
        批量处理数据
        Args:
            items: 待处理的数据列表
            batch_size: 批次大小,默认为None(全部处理)
        Returns:
            List[dict]: 处理后的数据列表
        """
        if batch_size is None:
            batch_size = len(items)
        results = []
        for i in range(0, len(items), batch_size):
            batch = items[i:i + batch_size]
            processed = self._process_batch(batch)
            results.extend(processed)
        return results
    def _process_batch(self, batch: List[dict]) -> List[dict]:
        """处理单个批次(私有方法)"""
        return [{"processed": True, **item} for item in batch]
# 复杂类型提示示例
def get_user_stats(users: List[Dict[str, Union[str, int, List[str]]]]) -> Dict[str, float]:
    """获取用户统计数据"""
    stats = {
        "average_age": 0.0,
        "total_users": len(users)
    }
    if users:
        ages = [user.get("age", 0) for user in users if isinstance(user.get("age"), (int, float))]
        stats["average_age"] = sum(ages) / len(ages) if ages else 0.0
    return stats

异常处理规范

class DatabaseError(Exception):
    """数据库操作错误"""
    pass
class ValidationError(Exception):
    """数据验证错误"""
    pass
class UserService:
    def get_user(self, user_id: int) -> dict:
        """
        获取用户信息
        Args:
            user_id: 用户ID
        Returns:
            dict: 用户信息
        Raises:
            ValidationError: 当user_id无效时
            DatabaseError: 当数据库操作失败时
        """
        try:
            if not isinstance(user_id, int) or user_id <= 0:
                raise ValidationError(f"无效的用户ID: {user_id}")
            # 模拟数据库查询
            user_data = self._query_database(user_id)
            if not user_data:
                raise DatabaseError(f"用户{user_id}不存在")
            return user_data
        except ValidationError:
            raise  # 重新抛出验证错误
        except DatabaseError:
            # 记录日志后重新抛出
            self._log_error(f"数据库查询失败: user_id={user_id}")
            raise
        except Exception as e:
            # 捕获未知异常
            self._log_error(f"未知错误: {str(e)}")
            raise DatabaseError(f"获取用户信息失败: {str(e)}")
    def _query_database(self, user_id: int) -> Optional[dict]:
        """模拟数据库查询"""
        # 这里应该是实际的数据库查询逻辑
        return None
    def _log_error(self, message: str):
        """记录错误日志"""
        print(f"ERROR: {message}")

上下文管理器

class DatabaseConnection:
    """数据库连接上下文管理器"""
    def __init__(self, connection_string: str):
        self.connection_string = connection_string
        self.connection = None
    def __enter__(self):
        print(f"连接数据库: {self.connection_string}")
        self.connection = {"connected": True}
        return self.connection
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("关闭数据库连接")
        self.connection = None
        # 处理异常
        if exc_type is not None:
            print(f"发生异常: {exc_type.__name__}: {exc_val}")
        # 返回False表示不抑制异常,True表示抑制异常
        return False
# 使用上下文管理器
def process_user_data(user_id: int):
    """处理用户数据"""
    with DatabaseConnection("mysql://localhost:3306/db") as conn:
        # 执行数据库操作
        if conn["connected"]:
            print(f"处理用户{user_id}的数据")
            # 这里可能会抛出异常

日志记录规范

import logging
from logging.handlers import RotatingFileHandler
# 配置日志系统
def setup_logger(name: str, log_file: str) -> logging.Logger:
    """配置日志记录器"""
    # 创建日志记录器
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    # 创建控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_format = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    console_handler.setFormatter(console_format)
    # 创建文件处理器(带轮转)
    file_handler = RotatingFileHandler(
        log_file, maxBytes=10*1024*1024, backupCount=5
    )
    file_handler.setLevel(logging.DEBUG)
    file_format = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
    )
    file_handler.setFormatter(file_format)
    # 添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)
    return logger
# 使用日志
logger = setup_logger("myapp", "app.log")
def api_request(endpoint: str, data: dict) -> dict:
    """API请求函数"""
    logger.info(f"开始API请求: {endpoint}")
    logger.debug(f"请求数据: {data}")
    try:
        # 模拟API请求
        result = {"status": 200, "data": data}
        logger.info(f"API请求成功: {endpoint}")
        return result
    except Exception as e:
        logger.error(f"API请求失败: {str(e)}", exc_info=True)
        raise

完整项目结构示例

# project/
# ├── src/
# │   ├── __init__.py
# │   ├── models/
# │   │   ├── __init__.py
# │   │   └── user.py
# │   ├── services/
# │   │   ├── __init__.py
# │   │   └── user_service.py
# │   ├── utils/
# │   │   ├── __init__.py
# │   │   └── validators.py
# │   └── main.py
# ├── tests/
# │   ├── __init__.py
# │   ├── test_user_service.py
# │   └── test_validators.py
# ├── config.py
# ├── requirements.txt
# └── README.md
# src/services/user_service.py
class UserService:
    """用户业务逻辑服务"""
    def __init__(self, db_connection, logger):
        self.db = db_connection
        self.logger = logger
    def create_user(self, user_data: dict) -> dict:
        """
        创建新用户
        Args:
            user_data: 用户数据字典
        Returns:
            dict: 创建成功的用户数据
        Raises:
            ValidationError: 数据验证失败
            DatabaseError: 数据库操作失败
        """
        try:
            # 验证数据
            self._validate_user_data(user_data)
            # 创建用户
            user = User(
                username=user_data["username"],
                email=user_data["email"],
                age=user_data.get("age")
            )
            # 保存到数据库
            self.db.save(user)
            # 记录日志
            self.logger.info(f"创建用户成功: {user.username}")
            return user.to_dict()
        except ValidationError as e:
            self.logger.warning(f"创建用户验证失败: {str(e)}")
            raise
        except Exception as e:
            self.logger.error(f"创建用户失败: {str(e)}", exc_info=True)
            raise DatabaseError("创建用户失败")
    def _validate_user_data(self, data: dict):
        """验证用户数据"""
        if not data.get("username"):
            raise ValidationError("用户名不能为空")
        if not data.get("email"):
            raise ValidationError("邮箱不能为空")
        if not self._is_valid_email(data["email"]):
            raise ValidationError("邮箱格式不正确")

这些规范案例涵盖了Python编程的各个方面,从基本的命名规则到完整的项目结构,实践中,你可以使用以下工具来自动检查代码规范:

  • Pylint: 代码规范检查
  • Black: 自动格式化代码
  • mypy: 类型检查
  • isort: 导入排序
  • pre-commit: Git钩子工具

建议在项目中配置 pyproject.tomlsetup.cfg 来统一规范配置。

标签: 编码规范

抱歉,评论功能暂时关闭!