本文目录导读:

我来帮你创建几个自动生成代码注释的脚本方案,覆盖不同语言和使用场景。
Python 通用注释生成器
#!/usr/bin/env python3
"""
自动代码注释生成器
支持 Python, JavaScript, Java, C/C++ 等语言
"""
import os
import re
import ast
from typing import List, Dict, Optional
class CodeCommentGenerator:
def __init__(self):
self.language_map = {
'.py': 'python',
'.js': 'javascript',
'.ts': 'typescript',
'.java': 'java',
'.c': 'c',
'.cpp': 'cpp',
'.h': 'c_header',
'.hpp': 'cpp_header'
}
def detect_language(self, file_path: str) -> str:
"""检测文件语言类型"""
ext = os.path.splitext(file_path)[1].lower()
return self.language_map.get(ext, 'unknown')
def generate_python_docstring(self, source: str) -> str:
"""为 Python 代码生成 docstring"""
try:
tree = ast.parse(source)
lines = source.split('\n')
new_lines = []
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
# 获取函数的行号
start_line = node.lineno - 1
# 检查是否已有 docstring
if (node.body and
isinstance(node.body[0], ast.Expr) and
isinstance(node.body[0].value, ast.Str)):
continue
# 生成 docstring
doc = self._generate_python_doc(node)
indent = ' ' * (node.col_offset + 4)
# 在函数定义后插入 docstring
insertion_line = start_line
while insertion_line < len(lines):
if lines[insertion_line].strip().endswith(':'):
break
insertion_line += 1
if insertion_line < len(lines):
doc_lines = [f"{indent}{line}" for line in doc.split('\n')]
new_lines.extend(lines[:insertion_line + 1])
new_lines.extend(doc_lines)
new_lines.extend(lines[insertion_line + 1:])
lines = new_lines
new_lines = []
return '\n'.join(lines)
except Exception as e:
print(f"Error parsing Python: {e}")
return source
def _generate_python_doc(self, node) -> str:
"""生成 Python docstring 内容"""
if isinstance(node, ast.FunctionDef):
params = [arg.arg for arg in node.args.args if arg.arg != 'self']
returns = self._get_return_type(node)
doc = '"""\n'
doc += f" {node.name} 函数\n\n"
doc += " 功能描述:\n [在此描述函数功能]\n\n"
if params:
doc += " 参数:\n"
for param in params:
doc += f" {param}: [参数类型] - [参数描述]\n"
doc += "\n"
if returns:
doc += f" 返回:\n [返回值类型] - [返回值描述]\n"
doc += ' """'
return doc
elif isinstance(node, ast.ClassDef):
doc = '"""\n'
doc += f" {node.name} 类\n\n"
doc += " 功能描述:\n [在此描述类功能]\n\n"
doc += " 属性:\n"
for item in node.body:
if isinstance(item, ast.FunctionDef) and item.name == '__init__':
for arg in item.args.args[1:]:
doc += f" {arg.arg}: [属性描述]\n"
doc += '\n """'
return doc
return '"""\n [在此添加文档]\n """'
def _get_return_type(self, node) -> Optional[str]:
"""获取函数返回类型"""
if node.returns:
return ast.dump(node.returns)
return None
def generate_js_comment(self, source: str) -> str:
"""为 JavaScript/TypeScript 生成 JSDoc 注释"""
# 匹配函数声明
pattern = r'(function\s+\w+\s*\([^)]*\)|const\s+\w+\s*=\s*\([^)]*\)\s*=>|class\s+\w+)'
lines = source.split('\n')
new_lines = []
for i, line in enumerate(lines):
match = re.match(r'^(\s*)(function\s+\w+\s*\([^)]*\)|const\s+\w+\s*=\s*\([^)]*\)\s*=>|class\s+\w+)', line)
if match:
indent = match.group(1)
declaration = match.group(2)
# 检查是否已有注释
if i > 0 and '/**' in lines[i-1]:
new_lines.append(line)
continue
# 生成 JSDoc 注释
comment_lines = self._generate_js_doc(declaration, indent)
new_lines.extend(comment_lines)
new_lines.append(line)
else:
new_lines.append(line)
return '\n'.join(new_lines)
def _generate_js_doc(self, declaration: str, indent: str) -> List[str]:
"""生成 JavaScript JSDoc 注释"""
comments = []
comments.append(f"{indent}/**")
comments.append(f"{indent} * [功能描述]")
# 提取参数
params = re.findall(r'\(\s*([^)]*)\)', declaration)
if params and params[0].strip():
params_list = [p.split(':')[0].strip() for p in params[0].split(',')]
comments.append(f"{indent} *")
for param in params_list:
if param and param != ')':
comments.append(f"{indent} * @param {{{param}}} - [参数描述]")
comments.append(f"{indent} * @returns [返回值描述]")
comments.append(f"{indent} */")
return comments
def generate_c_comment(self, source: str) -> str:
"""为 C/C++ 生成 Doxygen 注释"""
# 匹配函数定义
pattern = r'^(\w[\w\s\*]*?)\s+(\w+)\s*\(([^)]*)\)\s*\{'
lines = source.split('\n')
new_lines = []
for i, line in enumerate(lines):
match = re.match(r'^(\s*)([\w\*]+\s+\w+\s*\([^)]*\))\s*\{?', line)
if match and i > 0 and '/**' not in lines[i-1]:
indent = match.group(1)
func_signature = match.group(2)
# 生成 Doxygen 注释
comments = self._generate_c_doc(func_signature, indent)
new_lines.extend(comments)
new_lines.append(line)
else:
new_lines.append(line)
return '\n'.join(new_lines)
def _generate_c_doc(self, signature: str, indent: str) -> List[str]:
"""生成 C/C++ Doxygen 注释"""
comments = []
comments.append(f"{indent}/**")
comments.append(f"{indent} * @brief [函数功能简述]")
comments.append(f"{indent} * [详细描述]")
comments.append(f"{indent} *")
# 提取参数
params = re.findall(r'\(([^)]*)\)', signature)
if params and params[0].strip():
for param in params[0].split(','):
if param.strip():
parts = param.strip().split()
if len(parts) >= 2:
type_name = ' '.join(parts[:-1])
param_name = parts[-1]
comments.append(f"{indent} * @param {param_name} [参数描述]")
comments.append(f"{indent} * @return [返回值描述]")
comments.append(f"{indent} */")
return comments
def process_file(self, file_path: str) -> bool:
"""处理单个文件"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
source = f.read()
lang = self.detect_language(file_path)
result = source
if lang == 'python':
result = self.generate_python_docstring(source)
elif lang in ['javascript', 'typescript']:
result = self.generate_js_comment(source)
elif lang in ['c', 'cpp', 'c_header', 'cpp_header']:
result = self.generate_c_comment(source)
else:
print(f"不支持的文件类型: {file_path}")
return False
if result != source:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(result)
print(f"已更新注释: {file_path}")
return True
print(f"无需更新或无法处理: {file_path}")
return False
except Exception as e:
print(f"处理文件失败 {file_path}: {e}")
return False
def process_directory(self, directory: str, extensions: Optional[List[str]] = None):
"""处理目录下所有文件"""
if extensions is None:
extensions = ['.py', '.js', '.ts', '.java', '.c', '.cpp']
processed = 0
failed = 0
for root, dirs, files in os.walk(directory):
for filename in files:
ext = os.path.splitext(filename)[1].lower()
if ext in extensions:
file_path = os.path.join(root, filename)
try:
if self.process_file(file_path):
processed += 1
except Exception as e:
print(f"处理失败: {file_path} - {e}")
failed += 1
print(f"\n处理完成!成功: {processed} 个文件, 失败: {failed} 个文件")
# 命令行接口
def main():
import argparse
parser = argparse.ArgumentParser(description='自动代码注释生成器')
parser.add_argument('path', help='文件或目录路径')
parser.add_argument('--type', choices=['python', 'js', 'c'],
help='强制指定语言类型')
parser.add_argument('--extensions', nargs='+', default=None,
help='处理的文件扩展名列表')
args = parser.parse_args()
generator = CodeCommentGenerator()
if os.path.isfile(args.path):
generator.process_file(args.path)
elif os.path.isdir(args.path):
generator.process_directory(args.path, args.extensions)
else:
print("路径不存在!")
if __name__ == "__main__":
main()
Git 钩子 - 提交时自动添加注释
#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 开始自动生成代码注释..."
# 获取暂存的文件
staged_files=$(git diff --cached --name-only --diff-filter=ACM)
echo "检测到待处理文件:"
for file in $staged_files; do
echo " 📄 $file"
done
# 调用 Python 脚本处理注释
if [ -n "$staged_files" ]; then
for file in $staged_files; do
case "$file" in
*.py|*.js|*.ts|*.java)
python3 -m auto_comments "$file"
git add "$file"
echo " ✅ 已更新注释: $file"
;;
esac
done
fi
echo "✨ 注释生成完成!"
exit 0
IDE 扩展版(VS Code)
// comment-generator-extension.ts
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('自动注释生成器已激活');
// 注册命令:生成单个函数注释
let generateComment = vscode.commands.registerCommand(
'comment-generator.generateFunctionComment',
async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) return;
const document = editor.document;
const position = editor.selection.active;
const line = document.lineAt(position.line);
const languageId = document.languageId;
let comment = '';
// 根据语言生成不同风格的注释
switch (languageId) {
case 'python':
comment = generatePythonDoc();
break;
case 'javascript':
case 'typescript':
comment = generateJSComment();
break;
case 'c':
case 'cpp':
comment = generateCComment();
break;
default:
vscode.window.showErrorMessage('不支持的语言类型');
return;
}
// 插入注释
await editor.edit(editBuilder => {
editBuilder.insert(line.range.start, comment);
});
vscode.window.showInformationMessage('注释已生成!');
}
);
// 注册命令:批量生成整个文件注释
let generateFileComments = vscode.commands.registerCommand(
'comment-generator.generateFileComments',
async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) return;
const document = editor.document;
const text = document.getText();
// 这里调用后端 API 或本地脚本处理整个文件
vscode.window.showInformationMessage('正在处理整个文件...');
}
);
context.subscriptions.push(generateComment, generateFileComments);
}
function generatePythonDoc(): string {
return `"""
功能描述:
[在此描述函数功能]
参数:
[参数名]: [参数类型] - [参数描述]
返回:
[返回值类型] - [返回值描述]
"""
`;
}
function generateJSComment(): string {
return `/**
* [功能描述]
*
* @param {[类型]} [参数名] - [参数描述]
* @returns {[类型]} [返回值描述]
*/
`;
}
function generateCComment(): string {
return `/**
* @brief [函数功能简述]
*
* @param [参数名] [参数描述]
* @return [返回值描述]
*/
`;
}
使用说明
Python 脚本使用
# 添加执行权限 chmod +x auto_comments.py # 处理单个文件 python3 auto_comments.py path/to/file.py # 处理整个目录 python3 auto_comments.py ./src # 指定扩展名 python3 auto_comments.py ./src --extensions .py .js
Git Hook 配置
# 将脚本放到 .git/hooks/ 目录 chmod +x .git/hooks/pre-commit # 或者全局配置 git config --global core.hooksPath ~/.githooks
VS Code 扩展
安装到 VS Code:
- 将 TypeScript 代码转换为纯 JS 版本
- 或使用
yo code创建扩展项目 - 配置快捷键:
Ctrl+Shift+P→ 打开键盘快捷键设置
// keybindings.json
{
"key": "ctrl+alt+c",
"command": "comment-generator.generateFunctionComment"
}
高级功能建议
- AI 集成:可集成 ChatGPT 等 AI 服务生成更智能的注释
- 配置系统:支持通过 JSON/YAML 配置文件定制注释模板
- 多语言支持:扩展支持更多语言(Go、Rust、PHP 等)
- 代码分析:结合 AST 分析生成更准确的注释
- 批量处理:支持命令行批量处理和 CI/CD 集成
这些脚本可以根据你的具体需求进行定制和扩展!需要我详细解释某个部分或根据你的语言偏好调整吗?