一. 前言
使用Python脚本直接编译到指定目标文件夹
二. 代码
python
import compileall
import os
import shutil
from pathlib import Path
def compile_project(source_dir, target_dir=None, remove_source=False):
"""
编译Python项目为.pyc文件
Args:
source_dir: 源项目目录
target_dir: 目标目录(如果为None则在原目录编译)
remove_source: 是否删除源文件
"""
# clean_before_compile(source_dir, target_dir)
# 使用Path处理路径,避免转义问题
source_path = Path(source_dir).resolve()
if target_dir:
target_path = Path(target_dir).resolve()
# 检查目标目录是否已经存在且包含内容
if target_path.exists():
print(f"清理目标目录: {target_path}")
shutil.rmtree(target_path)
print(f"复制项目从 {source_path} 到 {target_path}")
# 使用copytree的dirs_exist_ok参数(Python 3.8+)
try:
# 排除不需要的目录和文件
shutil.copytree(
source_path,
target_path,
ignore=shutil.ignore_patterns(
'__pycache__', '*.pyc', '.git',
'A-deploy', '.idea', 'logs', 'test',
'*.log', '*.tmp', '.vscode'
)
)
except Exception as e:
print(f"复制失败: {e}")
return False
compile_dir = target_path
else:
compile_dir = source_path
print(f"开始编译目录: {compile_dir}")
try:
# 编译为.pyc文件
result = compileall.compile_dir(
str(compile_dir),
force=True,
legacy=True, # 生成.pyc而不是__pycache__
quiet=0
)
if result:
print(f"✅ 项目编译成功: {compile_dir}")
if remove_source:
# 安全地删除.py文件(保留入口文件)
py_files = []
for root, dirs, files in os.walk(compile_dir):
for file in files:
if file.endswith('.py'):
py_file = Path(root) / file
# 检查对应的.pyc文件是否存在
pyc_file = py_file.with_suffix('.pyc')
if pyc_file.exists():
py_files.append(py_file)
# 删除.py文件
for py_file in py_files:
if py_file.name == 'main.py':
pyc_file = py_file.with_suffix('.pyc')
pyc_file.unlink()
continue
py_file.unlink()
print(f"删除: {py_file}")
print(f"已删除 {len(py_files)} 个源文件")
else:
print("❌ 编译失败")
return False
except Exception as e:
print(f"❌ 编译过程中出错: {e}")
return False
return True
def clean_before_compile(source_dir, target_dir):
"""
编译前清理.pyc文件
"""
source_path = Path(source_dir)
target_path = Path(target_dir) if target_dir else None
print("🧹 编译前清理...")
# 清理源目录
clean_directory(source_path)
# 清理目标目录(如果存在)
if target_path and target_path.exists():
clean_directory(target_path)
def clean_directory(directory):
"""清理指定目录的.pyc文件"""
directory_path = Path(directory)
if not directory_path.exists():
return
# 删除.pyc文件
pyc_files = list(directory_path.rglob("*.pyc"))
for pyc_file in pyc_files:
try:
pyc_file.unlink()
print(f" 清理: {pyc_file}")
except Exception as e:
print(f" 清理失败: {pyc_file} - {e}")
# 删除__pycache__目录
cache_dirs = list(directory_path.rglob("__pycache__"))
for cache_dir in cache_dirs:
try:
shutil.rmtree(cache_dir)
print(f" 清理目录: {cache_dir}")
except Exception as e:
print(f" 清理目录失败: {cache_dir} - {e}")
if __name__ == "__main__":
source_dir = r"D:admin"
target_dir = r"D:admin\A-deploy\compiled_project"
compile_project(source_dir, target_dir, remove_source=True)
# clean_directory(source_dir)