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)
相关推荐
小程故事多_806 小时前
Agent Infra核心技术解析:Sandbox sandbox技术原理、选型逻辑与主流方案全景
java·开发语言·人工智能·aigc
沐知全栈开发6 小时前
SQL 日期处理指南
开发语言
黎雁·泠崖6 小时前
【魔法森林冒险】3/14 Allen类(一):主角核心属性与初始化
java·开发语言
黎雁·泠崖6 小时前
【魔法森林冒险】1/14 项目总览:用Java打造你的第一个回合制冒险游戏
java·开发语言
独好紫罗兰6 小时前
对python的再认识-基于数据结构进行-a006-元组-拓展
开发语言·数据结构·python
Dfreedom.6 小时前
图像直方图完全解析:从原理到实战应用
图像处理·python·opencv·直方图·直方图均衡化
C++ 老炮儿的技术栈6 小时前
Qt 编写 TcpClient 程序 详细步骤
c语言·开发语言·数据库·c++·qt·算法
yuuki2332336 小时前
【C++】继承
开发语言·c++·windows
222you6 小时前
Redis的主从复制和哨兵机制
java·开发语言
铉铉这波能秀6 小时前
LeetCode Hot100数据结构背景知识之集合(Set)Python2026新版
数据结构·python·算法·leetcode·哈希算法