Skip to main content

python

当进行Python代码审查、性能优化、类型安全检查或测试策略规划时,分析Python代码质量和最佳实践。

Datos de origen

Repositorio
microwind/ai-skills
Última actividad en el origen
29 de marzo de 2026 a las 10:03
Idioma detectado de SKILL.md
chino
Estrellas
83
Forks
24

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
5 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
Python分析器
description
当进行Python代码审查、性能优化、类型安全检查或测试策略规划时,分析Python代码质量和最佳实践。
license
MIT
# Python分析器技能 ## 概述 Python让编写糟糕代码变得容易。分析代码质量以防止技术债务。 **核心原则**: Python让编写糟糕代码变得容易。分析代码质量以防止技术债务。 ## 何时使用 **始终:** - Python代码审查 - 性能优化 - 类型安全检查 - 测试策略规划 - 代码重构 - 架构设计评审 **触发短语:** - "分析Python代码" - "Python性能优化" - "代码质量检查" - "Python最佳实践" - "类型安全分析" - "测试覆盖率" ## Python分析功能 ### 代码质量 - PEP 8规范检查 - 代码复杂度分析 - 代码重复检测 - 命名规范检查 - 文档字符串审查 ### 性能分析 - 瓶颈识别 - 内存使用分析 - 算法复杂度评估 - 并发性能检查 - I/O优化建议 ### 类型安全 - 类型注解检查 - 类型推断分析 - 类型错误检测 - mypy兼容性 - 运行时类型验证 ## 常见Python问题 ### 代码风格问题 ``` 问题: 不符合PEP 8编码规范 错误示例: - 变量名使用驼峰命名 - 行长度超过79字符 - 缺少空行分隔 - 导入语句不规范 解决方案: 1. 使用black自动格式化 2. 配置flake8检查 3. 使用isort整理导入 4. 遵循PEP 8指南 ``` ### 性能问题 ``` 问题: Python代码性能低下 错误示例: - 在循环中使用+拼接字符串 - 不必要的列表推导 - 全局变量访问 - 缺少缓存机制 解决方案: 1. 使用join拼接字符串 2. 优化数据结构选择 3. 使用局部变量 4. 实现缓存策略 ``` ### 类型安全问题 ``` 问题: 缺少类型注解导致运行时错误 错误示例: - 函数参数无类型提示 - 返回值类型不明确 - 可选参数未标注 - 泛型使用不当 解决方案: 1. 添加类型注解 2. 使用Optional标注可选值 3. 使用TypeVar定义泛型 4. 运行mypy检查 ``` ## 代码实现示例 ### Python代码分析器 ```python import ast import os import re from collections import defaultdict from typing import List, Dict, Any, Optional from dataclasses import dataclass from pathlib import Path @dataclass class CodeIssue: """代码问题""" file_path: str line_number: int column: int severity: str # error, warning, info message: str rule_id: str suggestion: Optional[str] = None @dataclass class FunctionMetrics: """函数指标""" name: str line_start: int line_end: int complexity: int arguments: int returns: int docstring: bool type_annotations: bool @dataclass class ClassMetrics: """类指标""" name: str line_start: int line_end: int methods: int attributes: int inheritance_depth: int docstring: bool class PythonAnalyzer: def __init__(self, config: Optional[Dict] = None): self.config = config or self.get_default_config() self.issues: List[CodeIssue] = [] self.function_metrics: List[FunctionMetrics] = [] self.class_metrics: List[ClassMetrics] = [] self.imports: Dict[str, List[str]] = defaultdict(list) self.complexity_threshold = self.config.get('complexity_threshold', 10) def get_default_config(self) -> Dict: """获取默认配置""" return { 'max_line_length': 79, 'max_function_length': 50, 'max_class_length': 200, 'complexity_threshold': 10, 'require_type_annotations': True, 'require_docstrings': True, 'check_imports': True, 'check_naming': True } def analyze_file(self, file_path: str) -> Dict[str, Any]: """分析单个Python文件""" try: with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # 解析AST tree = ast.parse(content, filename=file_path) # 重置状态 self.issues = [] self.function_metrics = [] self.class_metrics = [] self.imports = defaultdict(list) # 执行各种分析 self.check_style(file_path, content) self.analyze_ast(tree, file_path) self.check_complexity(tree, file_path) self.check_type_safety(tree, file_path) self.check_documentation(tree, file_path) return { 'file_path': file_path, 'issues': self.issues, 'function_metrics': self.function_metrics, 'class_metrics': self.class_metrics, 'imports': dict(self.imports), 'summary': self.generate_summary() } except SyntaxError as e: return { 'file_path': file_path, 'error': f'语法错误: {e}', 'issues': [CodeIssue( file_path=file_path, line_number=e.lineno or 0, column=e.offset or 0, severity='error', message=f'语法错误: {e.msg}', rule_id='syntax_error' )] } except Exception as e: return { 'file_path': file_path, 'error': f'分析失败: {e}', 'issues': [] } def analyze_directory(self, directory: str) -> Dict[str, Any]: """分析整个目录""" results = [] all_issues = [] for root, dirs, files in os.walk(directory): # 跳过虚拟环境和缓存目录 dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['__pycache__', 'venv', 'env']] for file in files: if file.endswith('.py'): file_path = os.path.join(root, file) result = self.analyze_file(file_path) results.append(result) all_issues.extend(result.get('issues', [])) return { 'directory': directory, 'files': results, 'total_issues': len(all_issues), 'issue_summary': self.categorize_issues(all_issues), 'recommendations': self.generate_recommendations(all_issues) } def check_style(self, file_path: str, content: str) -> None: """检查代码风格""" lines = content.split('\n') for line_num, line in enumerate(lines, 1): # 检查行长度 if len(line) > self.config['max_line_length']: self.issues.append(CodeIssue( file_path=file_path, line_number=line_num, column=self.config['max_line_length'], severity='warning', message=f'行长度超过{self.config["max_line_length"]}字符', rule_id='line_too_long', suggestion='考虑拆分长行或使用括号换行' )) # 检查尾随空格 if line.endswith(' '): self.issues.append(CodeIssue( file_path=file_path, line_number=line_num, column=len(line.rstrip()), severity='info', message='行末有多余空格', rule_id='trailing_whitespace', suggestion='删除行末空格' )) # 检查Tab字符 if '\t' in line: self.issues.append(CodeIssue( file_path=file_path, line_number=line_num, column=line.find('\t'), severity='warning', message='使用了Tab字符,应该使用空格', rule_id='tab_character', suggestion='将Tab替换为4个空格' )) def analyze_ast(self, tree: ast.AST, file_path: str) -> None: """分析AST结构""" # 分析导入 for node in ast.walk(tree): if isinstance(node, ast.Import): for alias in node.names: self.imports['import'].append(alias.name) elif isinstance(node, ast.ImportFrom): module = node.module or '' for alias in node.names: self.imports['from'].append(f'{module}.{alias.name}') # 分析函数和类 for node in ast.walk(tree): if isinstance(node, ast.FunctionDef): self.analyze_function(node, file_path) elif isinstance(node, ast.ClassDef): self.analyze_class(node, file_path) def analyze_function(self, node: ast.FunctionDef, file_path: str) -> None: """分析函数""" # 计算复杂度 complexity = self.calculate_complexity(node) # 统计参数 args = len(node.args.args) + len(node.args.kwonlyargs) if node.args.vararg: args += 1 if node.args.kwarg: args += 1 # 检查返回语句 returns = len([n for n in ast.walk(node) if isinstance(n, ast.Return)]) # 检查文档字符串 has_docstring = (ast.get_docstring(node) is not None) # 检查类型注解 has_type_annotations = ( all(arg.annotation for arg in node.args.args) and (node.returns is not None) ) metrics = FunctionMetrics( name=node.name, line_start=node.lineno, line_end=node.end_lineno or node.lineno, complexity=complexity, arguments=args, returns=returns, docstring=has_docstring, type_annotations=has_type_annotations ) self.function_metrics.append(metrics) # 检查问题 if complexity > self.complexity_threshold: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno, column=0, severity='warning', message=f'函数{node.name}复杂度过高({complexity})', rule_id='high_complexity', suggestion='考虑拆分函数或简化逻辑' )) if not has_docstring and self.config['require_docstrings']: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno, column=0, severity='info', message=f'函数{node.name}缺少文档字符串', rule_id='missing_docstring', suggestion='添加函数文档说明' )) if not has_type_annotations and self.config['require_type_annotations']: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno, column=0, severity='info', message=f'函数{node.name}缺少类型注解', rule_id='missing_type_annotations', suggestion='添加参数和返回值类型注解' )) def analyze_class(self, node: ast.ClassDef, file_path: str) -> None: """分析类""" # 统计方法和属性 methods = 0 attributes = 0 for item in node.body: if isinstance(item, ast.FunctionDef): methods += 1 elif isinstance(item, ast.Assign): for target in item.targets: if isinstance(target, ast.Name): attributes += 1 # 计算继承深度 inheritance_depth = self.calculate_inheritance_depth(node) # 检查文档字符串 has_docstring = (ast.get_docstring(node) is not None) metrics = ClassMetrics( name=node.name, line_start=node.lineno, line_end=node.end_lineno or node.lineno, methods=methods, attributes=attributes, inheritance_depth=inheritance_depth, docstring=has_docstring ) self.class_metrics.append(metrics) # 检查问题 if inheritance_depth > 3: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno, column=0, severity='warning', message=f'类{node.name}继承层次过深({inheritance_depth})', rule_id='deep_inheritance', suggestion='考虑使用组合替代继承' )) if not has_docstring and self.config['require_docstrings']: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno, column=0, severity='info', message=f'类{node.name}缺少文档字符串', rule_id='missing_docstring', suggestion='添加类文档说明' )) def calculate_complexity(self, node: ast.AST) -> int: """计算圈复杂度""" complexity = 1 # 基础复杂度 for child in ast.walk(node): if isinstance(child, (ast.If, ast.While, ast.For, ast.AsyncFor)): complexity += 1 elif isinstance(child, ast.ExceptHandler): complexity += 1 elif isinstance(child, ast.With, ast.AsyncWith): complexity += 1 elif isinstance(child, ast.BoolOp): complexity += len(child.values) - 1 return complexity def calculate_inheritance_depth(self, node: ast.ClassDef) -> int: """计算继承深度""" if not node.bases: return 0 max_depth = 0 for base in node.bases: if isinstance(base, ast.Name): # 简化实现,实际需要解析整个模块 max_depth = max(max_depth, 1) return max_depth def check_complexity(self, tree: ast.AST, file_path: str) -> None: """检查复杂度相关问题""" # 检查嵌套深度 for node in ast.walk(tree): if isinstance(node, (ast.For, ast.While, ast.If)): depth = self.calculate_nesting_depth(node) if depth > 3: self.issues.append(CodeIssue( file_path=file_path, line_number=node.lineno,
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub