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)
相关推荐
百锦再2 分钟前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven
条tiao条11 分钟前
KMP 算法详解:告别暴力匹配,让字符串匹配 “永不回头”
开发语言·算法
guts35013 分钟前
图像篡改数据集下载:COVERAGE、CASIA
python·数据集
干啥啥不行,秃头第一名17 分钟前
C++20概念(Concepts)入门指南
开发语言·c++·算法
森林猿25 分钟前
java-modbus-读取-modbus4j
java·网络·python
2401_8796938735 分钟前
将Python Web应用部署到服务器(Docker + Nginx)
jvm·数据库·python
2301_8073671943 分钟前
C++中的解释器模式变体
开发语言·c++·算法
chushiyunen1 小时前
python chatTts实现tts文本转语音、音频
python
FreakStudio1 小时前
把 Flask 搬进 ESP32,高中生自研嵌入式 Web 框架 MicroFlask !
python·单片机·嵌入式·cortex-m3·异步编程·电子diy
always_TT1 小时前
C语言中的字符与字符串(char数组)
c语言·开发语言