123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- 项目结构优化脚本
- 用于重新组织项目文件结构,创建更清晰的目录布局
- """
- import os
- import shutil
- from pathlib import Path
- def create_project_structure():
- """创建标准的项目目录结构"""
- base_dir = Path.cwd()
-
- # 定义目录结构
- directories = [
- 'src', # 源代码目录
- 'src/core', # 核心模块
- 'src/utils', # 工具模块
- 'src/config', # 配置模块
- 'tests', # 测试目录
- 'docs', # 文档目录
- 'examples', # 示例代码
- 'scripts', # 脚本目录
- 'data', # 数据目录
- 'data/models', # 模型文件
- 'data/samples', # 样本数据
- 'output', # 输出目录
- 'logs', # 日志目录
- ]
-
- # 创建目录
- for directory in directories:
- dir_path = base_dir / directory
- dir_path.mkdir(parents=True, exist_ok=True)
- print(f"✓ 创建目录: {directory}")
-
- return base_dir, directories
- def move_files_to_structure(base_dir):
- """将现有文件移动到新的目录结构中"""
-
- # 文件移动映射
- file_moves = {
- # 核心模块
- 'detector.py': 'src/core/',
- 'image_processor.py': 'src/core/',
- 'model_inference.py': 'src/core/',
- 'post_processor.py': 'src/core/',
- 'file_manager.py': 'src/utils/',
- 'report_generator.py': 'src/utils/',
-
- # 配置模块
- 'config.py': 'src/config/',
-
- # 主入口
- 'main.py': 'src/',
-
- # 测试文件
- 'test_refactored.py': 'tests/',
-
- # 脚本
- 'organize_project.py': 'scripts/',
-
- # 模型文件
- 'model/': 'data/models/',
- }
-
- # 执行文件移动
- for src_path, dst_dir in file_moves.items():
- src_full = base_dir / src_path
- dst_full = base_dir / dst_dir
-
- if src_full.exists():
- if src_full.is_dir():
- # 移动目录
- dst_path = dst_full / src_full.name
- if dst_path.exists():
- shutil.rmtree(dst_path)
- shutil.move(str(src_full), str(dst_full))
- print(f"✓ 移动目录: {src_path} -> {dst_dir}")
- else:
- # 移动文件
- dst_path = dst_full / src_full.name
- if dst_path.exists():
- dst_path.unlink()
- shutil.move(str(src_full), str(dst_full))
- print(f"✓ 移动文件: {src_path} -> {dst_dir}")
- else:
- print(f"⚠ 文件不存在: {src_path}")
- def create_init_files(base_dir):
- """创建__init__.py文件"""
- init_files = [
- 'src/__init__.py',
- 'src/core/__init__.py',
- 'src/utils/__init__.py',
- 'src/config/__init__.py',
- 'tests/__init__.py',
- ]
-
- for init_file in init_files:
- init_path = base_dir / init_file
- if not init_path.exists():
- init_path.write_text('# -*- coding: utf-8 -*-\n')
- print(f"✓ 创建: {init_file}")
- def update_imports_in_files(base_dir):
- """更新文件中的导入路径"""
- # 需要更新导入的文件
- files_to_update = [
- 'src/main.py',
- 'src/core/detector.py',
- 'tests/test_refactored.py',
- ]
-
- # 导入路径映射
- import_mapping = {
- 'from config import': 'from src.config.config import',
- 'from detector import': 'from src.core.detector import',
- 'from image_processor import': 'from src.core.image_processor import',
- 'from model_inference import': 'from src.core.model_inference import',
- 'from post_processor import': 'from src.core.post_processor import',
- 'from file_manager import': 'from src.utils.file_manager import',
- 'from report_generator import': 'from src.utils.report_generator import',
- }
-
- for file_path in files_to_update:
- full_path = base_dir / file_path
- if full_path.exists():
- try:
- content = full_path.read_text(encoding='utf-8')
-
- # 更新导入语句
- for old_import, new_import in import_mapping.items():
- content = content.replace(old_import, new_import)
-
- full_path.write_text(content, encoding='utf-8')
- print(f"✓ 更新导入: {file_path}")
- except Exception as e:
- print(f"⚠ 更新失败 {file_path}: {e}")
- def create_setup_files(base_dir):
- """创建项目配置文件"""
-
- # 创建setup.py
- setup_content = '''#!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- from setuptools import setup, find_packages
- with open("README.md", "r", encoding="utf-8") as fh:
- long_description = fh.read()
- with open("requirements.txt", "r", encoding="utf-8") as fh:
- requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")]
- setup(
- name="uav-detector",
- version="2.0.0",
- author="UAV Detection Team",
- description="基于ONNX的无人机检测系统",
- long_description=long_description,
- long_description_content_type="text/markdown",
- packages=find_packages(),
- classifiers=[
- "Development Status :: 4 - Beta",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
- "Programming Language :: Python :: 3.10",
- ],
- python_requires=">=3.8",
- install_requires=requirements,
- entry_points={
- "console_scripts": [
- "uav-detect=src.main:main",
- ],
- },
- )
- '''
-
- setup_path = base_dir / 'setup.py'
- setup_path.write_text(setup_content, encoding='utf-8')
- print("✓ 创建: setup.py")
-
- # 创建.gitignore
- gitignore_content = '''# Python
- __pycache__/
- *.py[cod]
- *$py.class
- *.so
- .Python
- build/
- develop-eggs/
- dist/
- downloads/
- eggs/
- .eggs/
- lib/
- lib64/
- parts/
- sdist/
- var/
- wheels/
- *.egg-info/
- .installed.cfg
- *.egg
- PIPFILE.lock
- # Virtual Environment
- .venv/
- venv/
- ENV/
- env/
- # IDE
- .vscode/
- .idea/
- *.swp
- *.swo
- *~
- # OS
- .DS_Store
- .DS_Store?
- ._*
- .Spotlight-V100
- .Trashes
- ehthumbs.db
- Thumbs.db
- # Project specific
- output/
- logs/
- *.log
- data/samples/*
- !data/samples/.gitkeep
- '''
-
- gitignore_path = base_dir / '.gitignore'
- if not gitignore_path.exists():
- gitignore_path.write_text(gitignore_content, encoding='utf-8')
- print("✓ 创建: .gitignore")
- def create_placeholder_files(base_dir):
- """创建占位文件"""
- placeholders = [
- ('data/samples/.gitkeep', ''),
- ('logs/.gitkeep', ''),
- ('output/.gitkeep', ''),
- ('docs/API.md', '# API 文档\n\n待完善...\n'),
- ('examples/basic_usage.py', '#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\n"""基本使用示例"""\n\n# 待完善...\n'),
- ]
-
- for file_path, content in placeholders:
- full_path = base_dir / file_path
- if not full_path.exists():
- full_path.write_text(content, encoding='utf-8')
- print(f"✓ 创建占位文件: {file_path}")
- def main():
- """主函数"""
- print("🚀 开始项目结构重构...")
- print("=" * 50)
-
- try:
- # 1. 创建目录结构
- print("\n📁 创建目录结构...")
- base_dir, directories = create_project_structure()
-
- # 2. 移动文件
- print("\n📦 移动文件到新结构...")
- move_files_to_structure(base_dir)
-
- # 3. 创建__init__.py文件
- print("\n📄 创建__init__.py文件...")
- create_init_files(base_dir)
-
- # 4. 更新导入路径
- print("\n🔄 更新导入路径...")
- update_imports_in_files(base_dir)
-
- # 5. 创建配置文件
- print("\n⚙️ 创建项目配置文件...")
- create_setup_files(base_dir)
-
- # 6. 创建占位文件
- print("\n📝 创建占位文件...")
- create_placeholder_files(base_dir)
-
- print("\n" + "=" * 50)
- print("🎉 项目结构重构完成!")
- print("\n新的项目结构:")
- print("├── src/ # 源代码")
- print("│ ├── core/ # 核心模块")
- print("│ ├── utils/ # 工具模块")
- print("│ ├── config/ # 配置模块")
- print("│ └── main.py # 主入口")
- print("├── tests/ # 测试代码")
- print("├── docs/ # 文档")
- print("├── examples/ # 示例代码")
- print("├── scripts/ # 脚本")
- print("├── data/ # 数据文件")
- print("│ ├── models/ # 模型文件")
- print("│ └── samples/ # 样本数据")
- print("├── output/ # 输出目录")
- print("├── logs/ # 日志目录")
- print("├── setup.py # 安装配置")
- print("├── requirements.txt # 依赖列表")
- print("└── README.md # 项目说明")
-
- except Exception as e:
- print(f"❌ 重构过程中出现错误: {e}")
- return False
-
- return True
- if __name__ == '__main__':
- success = main()
- if success:
- print("\n✅ 可以使用以下命令测试新结构:")
- print(" python -m src.main --help")
- print(" python -m pytest tests/")
- else:
- print("\n❌ 重构失败,请检查错误信息")
|