python - 【编译.py文件】部署运行

一. 前言

使用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)
相关推荐
SelectDB12 小时前
Apache Doris Python UDF:让 SQL 直接调用 Python 生态,支撑 Agent 时代复杂业务逻辑
大数据·数据库·python
荣码20 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
金銀銅鐵1 天前
[Python] 基于欧几里得算法,实现分数约分计算器
python·数学
Lyn_Li1 天前
Kaggle Top 5 | 198只股票、200条数据的金融预测——BattleFin高分方案从零复现
python·kaggle·比赛复盘·金融预测
小九九的爸爸2 天前
前端想要入门Agent开发,要具备哪些Python基础?
python·agent·ai编程
阿耶同学2 天前
手把手教你用 LangGraph 搭建三层嵌套 Agent 架构
python·程序员
花酒锄作田2 天前
Pydantic校验配置文件
python
hboot2 天前
AI工程师第四课 - 深度学习入门
pytorch·python·神经网络
ZhengEnCi3 天前
P2M-Matplotlib折线图完全指南-从数据可视化到趋势分析的Python绘图利器
python·matlab·数据可视化
ZhengEnCi3 天前
P2L-Matplotlib饼图完全指南-从数据可视化到图表定制的Python绘图利器
python·matlab