Browse Source

增加dataAnalysisBehavior、dataAnalysisBusiness、dataAnalysisService、dataContract、repositoryZN 模块的setupModel.py,基于nuitka包实现 python源代码文件编译为pyd(windows)文件或so(linux)文件,并打包至 whl文件中

zhouyang.xie 1 tháng trước cách đây
mục cha
commit
874fcc979e

+ 54 - 153
dataAnalysisBehavior/setup.py

@@ -1,165 +1,66 @@
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.install import install
+import compileall
 import os
 import sys
-import re
 import shutil
-import subprocess
-from setuptools import setup, find_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.bdist_wheel import bdist_wheel
-
-# ========== 配置 ==========
-PACKAGE_NAME = "dataAnalysisBehavior"      # 包名(仅用于元数据)
-COMPILE_DIRS = ["behavior", "common"]      # 需要编译的子目录(同时也是顶层包名)
-INSTALL_REQUIRES = []                      # 根据实际依赖填写
-CLEAN_COMPILED_AFTER_BUILD = True
-# =========================
-
-def log(msg):
-    print(f"[SETUP] {msg}")
-
-def compile_with_nuitka(py_files):
-    for py_file in py_files:
-        if os.path.basename(py_file) == "__init__.py":
-            continue
-        log(f"编译: {py_file}")
+from pathlib import Path
 
-        output_dir = os.path.dirname(py_file)
-        cmd = [
-            sys.executable, "-m", "nuitka",
-            "--module",
-            "--no-pyi-file",
-            "--remove-output",
-            f"--output-dir={output_dir}",
-            py_file
-        ]
-        if sys.platform == "win32":
-            cmd.append("--mingw64")
-        result = subprocess.run(cmd, capture_output=True, text=True)
-        if result.returncode != 0:
-            log(f"编译失败: {py_file}\n{result.stderr}")
-            sys.exit(1)
-
-        base_name = os.path.splitext(os.path.basename(py_file))[0]
-        found = False
-        for ext in [".pyd", ".so"]:
-            pattern = re.escape(base_name) + r".*" + re.escape(ext)
-            for f in os.listdir(output_dir):
-                if re.match(pattern, f):
-                    src = os.path.join(output_dir, f)
-                    dst = os.path.join(output_dir, base_name + ext)
-                    shutil.move(src, dst)
-                    log(f"重命名: {src} -> {dst}")
-                    found = True
-                    break
-            if found:
-                break
-        if not found:
-            log(f"错误:未找到编译产物 {py_file}")
-            sys.exit(1)
-
-def clean_build_dir():
-    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
-    for d in dirs_to_clean:
-        if os.path.exists(d):
-            shutil.rmtree(d)
-            log(f"已删除: {d}")
+compileDirs=['common','behavior']
 
 class CustomBuildPy(build_py):
     def run(self):
-        src_root = os.getcwd()
-        log(f"源码根目录: {src_root}")
+        # 获取当前 Python 版本信息
+        py_version = f".cpython-{sys.version_info.major}{sys.version_info.minor}"
 
-        # 1. 编译生成 .pyd/.so
-        for compile_dir in COMPILE_DIRS:
-            target_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(target_dir):
-                log(f"警告: 目录不存在 {target_dir}")
-                continue
-            all_py = []
-            for root, _, files in os.walk(target_dir):
-                for file in files:
-                    if file.endswith(".py"):
-                        all_py.append(os.path.join(root, file))
-            if all_py:
-                compile_with_nuitka(all_py)
-            else:
-                log(f"在 {target_dir} 中没有找到 .py 文件")
+        for dir in compileDirs:
+            for root,_,subFiles in os.walk(dir):
+                compileall.compile_dir(root, force=True)
 
-        # 2. 手动构建目录:直接复制到 build/lib/{compile_dir}(不创建顶层包目录)
-        build_lib = self.build_lib
-        if not build_lib:
-            build_lib = os.path.join(src_root, "build", "lib")
+                for file in subFiles:
+                    if file.endswith('.pyc'):
+                        pyc_path = os.path.join(root, file)
+                        new_File = file.replace(py_version, '')
+                        new_path=os.path.join(Path(root).parent,new_File)
+                        shutil.move(pyc_path, new_path)
 
-        for compile_dir in COMPILE_DIRS:
-            src_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(src_dir):
-                continue
-            dst_dir = os.path.join(build_lib, compile_dir)   # 直接作为顶级包
-            self.mkpath(dst_dir)
-            for root, _, files in os.walk(src_dir):
-                rel_path = os.path.relpath(root, src_dir)
-                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
-                self.mkpath(target_subdir)
-                for file in files:
-                    src_file = os.path.join(root, file)
-                    if file == "__init__.py":
-                        # 复制 __init__.py
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    elif file.endswith(".pyd") or file.endswith(".so"):
-                        # 复制编译好的二进制文件
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    # 其他 .py 文件忽略不复制
+        super().run()
 
-        # 3. 可选:清理源码目录中的 .pyd/.so
-        if CLEAN_COMPILED_AFTER_BUILD:
-            for compile_dir in COMPILE_DIRS:
-                target_dir = os.path.join(src_root, compile_dir)
-                if not os.path.isdir(target_dir):
-                    continue
-                for root, _, files in os.walk(target_dir):
-                    for file in files:
-                        if file.endswith(".pyd") or file.endswith(".so"):
-                            os.remove(os.path.join(root, file))
-                            log(f"清理源码编译产物: {os.path.join(root, file)}")
-
-class CustomBdistWheel(bdist_wheel):
+class InstallCommand(install):
     def run(self):
-        self.run_command("build_py")
-        self.plat_name = self.get_platform()
-        bdist_wheel.run(self)
-
-    def get_platform(self):
-        if sys.platform == "win32":
-            return "win_amd64"
-        elif sys.platform == "linux":
-            return "linux_x86_64"
-        else:
-            return super().get_platform()
-
-if __name__ == "__main__":
-    try:
-        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
-    except subprocess.CalledProcessError:
-        log("请先安装 Nuitka: pip install nuitka", "ERROR")
-        sys.exit(1)
-
-    clean_build_dir()
-
-    setup(
-        name=PACKAGE_NAME,
-        version="1.2.202508190930",
-        description="Data Analysis Behavior Package (compiled, no source in wheel)",
-        author="Xie Zhou Yang",
-        packages=["behavior", "common"],                # 直接指定顶层包
-        package_dir={"": "."},                          # 包目录在当前目录
-        cmdclass={
-            "build_py": CustomBuildPy,
-            "bdist_wheel": CustomBdistWheel,
-        },
-        install_requires=INSTALL_REQUIRES,
-        zip_safe=False,
-    )
+        super().run()
+        # Remove all .py files from the installed package
+        # 若用于开发,可查看导入的自定义package 则注释本代码段
+        # 若用于部署交付,可应用本代码
+        # for root, _, files in os.walk(self.install_lib):
+        #     for file in files:
+        #         if file.endswith('.py'):
+        #             os.remove(os.path.join(root, file))
+
+setup(
+    name='dataAnalysisBehavior',
+    # version='1.2.202406281546',
+    version='1.2.202505131730',
+    description='Data Analysis Behavior Package', # 描述信息
+    author='Xie Zhou Yang', # 作者
+    packages=find_packages(),
+    cmdclass={
+        'build_py': CustomBuildPy,
+        'install': InstallCommand,
+    },
+    package_data={
+        'behavior': ['*.pyc'],
+        'common': ['*.pyc']
+    },
+    exclude_package_data={'': ['*.py']}
+)
+
+# 获取 setup.py 所在的绝对路径
+setup_dir = os.path.abspath(os.path.dirname(__file__))
+# 编译打包后,删除pyc后缀文件
+for root, _, files in os.walk(setup_dir):
+    for file in files:
+        if file.endswith('.pyc') or file.endswith('.c'):
+            print(os.path.join(root, file))
+            os.remove(os.path.join(root, file))

+ 165 - 0
dataAnalysisBehavior/setupModel.py

@@ -0,0 +1,165 @@
+import os
+import sys
+import re
+import shutil
+import subprocess
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.bdist_wheel import bdist_wheel
+
+# ========== 配置 ==========
+PACKAGE_NAME = "dataAnalysisBehavior"      # 包名(仅用于元数据)
+COMPILE_DIRS = ["behavior", "common"]      # 需要编译的子目录(同时也是顶层包名)
+INSTALL_REQUIRES = []                      # 根据实际依赖填写
+CLEAN_COMPILED_AFTER_BUILD = True
+# =========================
+
+def log(msg):
+    print(f"[SETUP] {msg}")
+
+def compile_with_nuitka(py_files):
+    for py_file in py_files:
+        if os.path.basename(py_file) == "__init__.py":
+            continue
+        log(f"编译: {py_file}")
+
+        output_dir = os.path.dirname(py_file)
+        cmd = [
+            sys.executable, "-m", "nuitka",
+            "--module",
+            "--no-pyi-file",
+            "--remove-output",
+            f"--output-dir={output_dir}",
+            py_file
+        ]
+        if sys.platform == "win32":
+            cmd.append("--mingw64")
+        result = subprocess.run(cmd, capture_output=True, text=True)
+        if result.returncode != 0:
+            log(f"编译失败: {py_file}\n{result.stderr}")
+            sys.exit(1)
+
+        base_name = os.path.splitext(os.path.basename(py_file))[0]
+        found = False
+        for ext in [".pyd", ".so"]:
+            pattern = re.escape(base_name) + r".*" + re.escape(ext)
+            for f in os.listdir(output_dir):
+                if re.match(pattern, f):
+                    src = os.path.join(output_dir, f)
+                    dst = os.path.join(output_dir, base_name + ext)
+                    shutil.move(src, dst)
+                    log(f"重命名: {src} -> {dst}")
+                    found = True
+                    break
+            if found:
+                break
+        if not found:
+            log(f"错误:未找到编译产物 {py_file}")
+            sys.exit(1)
+
+def clean_build_dir():
+    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
+    for d in dirs_to_clean:
+        if os.path.exists(d):
+            shutil.rmtree(d)
+            log(f"已删除: {d}")
+
+class CustomBuildPy(build_py):
+    def run(self):
+        src_root = os.getcwd()
+        log(f"源码根目录: {src_root}")
+
+        # 1. 编译生成 .pyd/.so
+        for compile_dir in COMPILE_DIRS:
+            target_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(target_dir):
+                log(f"警告: 目录不存在 {target_dir}")
+                continue
+            all_py = []
+            for root, _, files in os.walk(target_dir):
+                for file in files:
+                    if file.endswith(".py"):
+                        all_py.append(os.path.join(root, file))
+            if all_py:
+                compile_with_nuitka(all_py)
+            else:
+                log(f"在 {target_dir} 中没有找到 .py 文件")
+
+        # 2. 手动构建目录:直接复制到 build/lib/{compile_dir}(不创建顶层包目录)
+        build_lib = self.build_lib
+        if not build_lib:
+            build_lib = os.path.join(src_root, "build", "lib")
+
+        for compile_dir in COMPILE_DIRS:
+            src_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(src_dir):
+                continue
+            dst_dir = os.path.join(build_lib, compile_dir)   # 直接作为顶级包
+            self.mkpath(dst_dir)
+            for root, _, files in os.walk(src_dir):
+                rel_path = os.path.relpath(root, src_dir)
+                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
+                self.mkpath(target_subdir)
+                for file in files:
+                    src_file = os.path.join(root, file)
+                    if file == "__init__.py":
+                        # 复制 __init__.py
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    elif file.endswith(".pyd") or file.endswith(".so"):
+                        # 复制编译好的二进制文件
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    # 其他 .py 文件忽略不复制
+
+        # 3. 可选:清理源码目录中的 .pyd/.so
+        if CLEAN_COMPILED_AFTER_BUILD:
+            for compile_dir in COMPILE_DIRS:
+                target_dir = os.path.join(src_root, compile_dir)
+                if not os.path.isdir(target_dir):
+                    continue
+                for root, _, files in os.walk(target_dir):
+                    for file in files:
+                        if file.endswith(".pyd") or file.endswith(".so"):
+                            os.remove(os.path.join(root, file))
+                            log(f"清理源码编译产物: {os.path.join(root, file)}")
+
+class CustomBdistWheel(bdist_wheel):
+    def run(self):
+        self.run_command("build_py")
+        self.plat_name = self.get_platform()
+        bdist_wheel.run(self)
+
+    def get_platform(self):
+        if sys.platform == "win32":
+            return "win_amd64"
+        elif sys.platform == "linux":
+            return "linux_x86_64"
+        else:
+            return super().get_platform()
+
+if __name__ == "__main__":
+    try:
+        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
+    except subprocess.CalledProcessError:
+        log("请先安装 Nuitka: pip install nuitka", "ERROR")
+        sys.exit(1)
+
+    clean_build_dir()
+
+    setup(
+        name=PACKAGE_NAME,
+        version="1.2.202508190930",
+        description="Data Analysis Behavior Package (compiled, no source in wheel)",
+        author="Xie Zhou Yang",
+        packages=["behavior", "common"],                # 直接指定顶层包
+        package_dir={"": "."},                          # 包目录在当前目录
+        cmdclass={
+            "build_py": CustomBuildPy,
+            "bdist_wheel": CustomBdistWheel,
+        },
+        install_requires=INSTALL_REQUIRES,
+        zip_safe=False,
+    )

+ 52 - 151
dataAnalysisBusiness/setup.py

@@ -1,163 +1,64 @@
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.install import install
+import compileall
 import os
 import sys
-import re
 import shutil
-import subprocess
-from setuptools import setup, find_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.bdist_wheel import bdist_wheel
-
-# ========== 配置 ==========
-PACKAGE_NAME = "dataAnalysisBusiness"
-COMPILE_DIRS = ["algorithm"]          # 需要编译的子目录(将作为顶层包)
-# INSTALL_REQUIRES = ["dataAnalysisBehavior"]   # 根据实际依赖填写
-INSTALL_REQUIRES = []
-CLEAN_COMPILED_AFTER_BUILD = True
-# =========================
-
-def log(msg):
-    print(f"[SETUP] {msg}")
-
-def compile_with_nuitka(py_files):
-    for py_file in py_files:
-        if os.path.basename(py_file) == "__init__.py":
-            continue
-        log(f"编译: {py_file}")
+from pathlib import Path
 
-        output_dir = os.path.dirname(py_file)
-        cmd = [
-            sys.executable, "-m", "nuitka",
-            "--module",
-            "--no-pyi-file",
-            "--remove-output",
-            f"--output-dir={output_dir}",
-            py_file
-        ]
-        if sys.platform == "win32":
-            cmd.append("--mingw64")
-        result = subprocess.run(cmd, capture_output=True, text=True)
-        if result.returncode != 0:
-            log(f"编译失败: {py_file}\n{result.stderr}")
-            sys.exit(1)
-
-        base_name = os.path.splitext(os.path.basename(py_file))[0]
-        found = False
-        for ext in [".pyd", ".so"]:
-            pattern = re.escape(base_name) + r".*" + re.escape(ext)
-            for f in os.listdir(output_dir):
-                if re.match(pattern, f):
-                    src = os.path.join(output_dir, f)
-                    dst = os.path.join(output_dir, base_name + ext)
-                    shutil.move(src, dst)
-                    log(f"重命名: {src} -> {dst}")
-                    found = True
-                    break
-            if found:
-                break
-        if not found:
-            log(f"错误:未找到编译产物 {py_file}")
-            sys.exit(1)
-
-def clean_build_dir():
-    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
-    for d in dirs_to_clean:
-        if os.path.exists(d):
-            shutil.rmtree(d)
-            log(f"已删除: {d}")
+compileDirs=['algorithm']
 
 class CustomBuildPy(build_py):
     def run(self):
-        src_root = os.getcwd()
-        log(f"源码根目录: {src_root}")
+        # 获取当前 Python 版本信息
+        py_version = f".cpython-{sys.version_info.major}{sys.version_info.minor}"
 
-        # 1. 编译生成 .pyd/.so
-        for compile_dir in COMPILE_DIRS:
-            target_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(target_dir):
-                log(f"警告: 目录不存在 {target_dir}")
-                continue
-            all_py = []
-            for root, _, files in os.walk(target_dir):
-                for file in files:
-                    if file.endswith(".py"):
-                        all_py.append(os.path.join(root, file))
-            if all_py:
-                compile_with_nuitka(all_py)
-            else:
-                log(f"在 {target_dir} 中没有找到 .py 文件")
+        for dir in compileDirs:
+            for root,_,subFiles in os.walk(dir):
+                compileall.compile_dir(root, force=True)
 
-        # 2. 手动构建:复制到 build/lib/{compile_dir}(直接作为顶级包)
-        build_lib = self.build_lib
-        if not build_lib:
-            build_lib = os.path.join(src_root, "build", "lib")
+                for file in subFiles:
+                    if file.endswith('.pyc'):
+                        pyc_path = os.path.join(root, file)
+                        new_File = file.replace(py_version, '')
+                        new_path=os.path.join(Path(root).parent,new_File)
+                        shutil.move(pyc_path, new_path)
 
-        for compile_dir in COMPILE_DIRS:
-            src_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(src_dir):
-                continue
-            dst_dir = os.path.join(build_lib, compile_dir)   # 顶级包
-            self.mkpath(dst_dir)
-            for root, _, files in os.walk(src_dir):
-                rel_path = os.path.relpath(root, src_dir)
-                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
-                self.mkpath(target_subdir)
-                for file in files:
-                    src_file = os.path.join(root, file)
-                    if file == "__init__.py":
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    elif file.endswith(".pyd") or file.endswith(".so"):
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
+        super().run()
 
-        # 3. 清理源码目录中的 .pyd/.so
-        if CLEAN_COMPILED_AFTER_BUILD:
-            for compile_dir in COMPILE_DIRS:
-                target_dir = os.path.join(src_root, compile_dir)
-                if not os.path.isdir(target_dir):
-                    continue
-                for root, _, files in os.walk(target_dir):
-                    for file in files:
-                        if file.endswith(".pyd") or file.endswith(".so"):
-                            os.remove(os.path.join(root, file))
-                            log(f"清理源码编译产物: {os.path.join(root, file)}")
-
-class CustomBdistWheel(bdist_wheel):
+class InstallCommand(install):
     def run(self):
-        self.run_command("build_py")
-        self.plat_name = self.get_platform()
-        bdist_wheel.run(self)
-
-    def get_platform(self):
-        if sys.platform == "win32":
-            return "win_amd64"
-        elif sys.platform == "linux":
-            return "linux_x86_64"
-        else:
-            return super().get_platform()
-
-if __name__ == "__main__":
-    try:
-        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
-    except subprocess.CalledProcessError:
-        log("请先安装 Nuitka: pip install nuitka", "ERROR")
-        sys.exit(1)
-
-    clean_build_dir()
-
-    setup(
-        name=PACKAGE_NAME,
-        version="1.2.202508190930",
-        description="Data Analysis Business Package (compiled, flat structure)",
-        author="Xie Zhou Yang",
-        packages=["algorithm"],                # 顶层包
-        package_dir={"": "."},
-        cmdclass={
-            "build_py": CustomBuildPy,
-            "bdist_wheel": CustomBdistWheel,
-        },
-        install_requires=INSTALL_REQUIRES,
-        zip_safe=False,
-    )
+        super().run()
+        # Remove all .py files from the installed package
+        # 若用于开发,可查看导入的自定义package 则注释本代码段
+        # 若用于部署交付,可应用本代码
+        # for root, _, files in os.walk(self.install_lib):
+        #     for file in files:
+        #         if file.endswith('.py'):
+        #             os.remove(os.path.join(root, file))
+
+setup(
+    name='dataAnalysisBusiness',
+    version='1.2.202505141510',
+    description='Data Analysis Business Package', # 描述信息
+    author='Xie Zhou Yang', # 作者
+    packages=find_packages(),
+    cmdclass={
+        'build_py': CustomBuildPy,
+        'install': InstallCommand,
+    },
+    package_data={
+        'algorithm': ['*.pyc']
+    },
+    exclude_package_data={'': ['*.py']}
+)
+
+# 获取 setup.py 所在的绝对路径
+setup_dir = os.path.abspath(os.path.dirname(__file__))
+# 编译打包后,删除pyc后缀文件
+for root, _, files in os.walk(setup_dir):
+    for file in files:
+        if file.endswith('.pyc') or file.endswith('.c'):
+            print(os.path.join(root, file))
+            os.remove(os.path.join(root, file))

+ 163 - 0
dataAnalysisBusiness/setupModel.py

@@ -0,0 +1,163 @@
+import os
+import sys
+import re
+import shutil
+import subprocess
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.bdist_wheel import bdist_wheel
+
+# ========== 配置 ==========
+PACKAGE_NAME = "dataAnalysisBusiness"
+COMPILE_DIRS = ["algorithm"]          # 需要编译的子目录(将作为顶层包)
+# INSTALL_REQUIRES = ["dataAnalysisBehavior"]   # 根据实际依赖填写
+INSTALL_REQUIRES = []
+CLEAN_COMPILED_AFTER_BUILD = True
+# =========================
+
+def log(msg):
+    print(f"[SETUP] {msg}")
+
+def compile_with_nuitka(py_files):
+    for py_file in py_files:
+        if os.path.basename(py_file) == "__init__.py":
+            continue
+        log(f"编译: {py_file}")
+
+        output_dir = os.path.dirname(py_file)
+        cmd = [
+            sys.executable, "-m", "nuitka",
+            "--module",
+            "--no-pyi-file",
+            "--remove-output",
+            f"--output-dir={output_dir}",
+            py_file
+        ]
+        if sys.platform == "win32":
+            cmd.append("--mingw64")
+        result = subprocess.run(cmd, capture_output=True, text=True)
+        if result.returncode != 0:
+            log(f"编译失败: {py_file}\n{result.stderr}")
+            sys.exit(1)
+
+        base_name = os.path.splitext(os.path.basename(py_file))[0]
+        found = False
+        for ext in [".pyd", ".so"]:
+            pattern = re.escape(base_name) + r".*" + re.escape(ext)
+            for f in os.listdir(output_dir):
+                if re.match(pattern, f):
+                    src = os.path.join(output_dir, f)
+                    dst = os.path.join(output_dir, base_name + ext)
+                    shutil.move(src, dst)
+                    log(f"重命名: {src} -> {dst}")
+                    found = True
+                    break
+            if found:
+                break
+        if not found:
+            log(f"错误:未找到编译产物 {py_file}")
+            sys.exit(1)
+
+def clean_build_dir():
+    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
+    for d in dirs_to_clean:
+        if os.path.exists(d):
+            shutil.rmtree(d)
+            log(f"已删除: {d}")
+
+class CustomBuildPy(build_py):
+    def run(self):
+        src_root = os.getcwd()
+        log(f"源码根目录: {src_root}")
+
+        # 1. 编译生成 .pyd/.so
+        for compile_dir in COMPILE_DIRS:
+            target_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(target_dir):
+                log(f"警告: 目录不存在 {target_dir}")
+                continue
+            all_py = []
+            for root, _, files in os.walk(target_dir):
+                for file in files:
+                    if file.endswith(".py"):
+                        all_py.append(os.path.join(root, file))
+            if all_py:
+                compile_with_nuitka(all_py)
+            else:
+                log(f"在 {target_dir} 中没有找到 .py 文件")
+
+        # 2. 手动构建:复制到 build/lib/{compile_dir}(直接作为顶级包)
+        build_lib = self.build_lib
+        if not build_lib:
+            build_lib = os.path.join(src_root, "build", "lib")
+
+        for compile_dir in COMPILE_DIRS:
+            src_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(src_dir):
+                continue
+            dst_dir = os.path.join(build_lib, compile_dir)   # 顶级包
+            self.mkpath(dst_dir)
+            for root, _, files in os.walk(src_dir):
+                rel_path = os.path.relpath(root, src_dir)
+                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
+                self.mkpath(target_subdir)
+                for file in files:
+                    src_file = os.path.join(root, file)
+                    if file == "__init__.py":
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    elif file.endswith(".pyd") or file.endswith(".so"):
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+
+        # 3. 清理源码目录中的 .pyd/.so
+        if CLEAN_COMPILED_AFTER_BUILD:
+            for compile_dir in COMPILE_DIRS:
+                target_dir = os.path.join(src_root, compile_dir)
+                if not os.path.isdir(target_dir):
+                    continue
+                for root, _, files in os.walk(target_dir):
+                    for file in files:
+                        if file.endswith(".pyd") or file.endswith(".so"):
+                            os.remove(os.path.join(root, file))
+                            log(f"清理源码编译产物: {os.path.join(root, file)}")
+
+class CustomBdistWheel(bdist_wheel):
+    def run(self):
+        self.run_command("build_py")
+        self.plat_name = self.get_platform()
+        bdist_wheel.run(self)
+
+    def get_platform(self):
+        if sys.platform == "win32":
+            return "win_amd64"
+        elif sys.platform == "linux":
+            return "linux_x86_64"
+        else:
+            return super().get_platform()
+
+if __name__ == "__main__":
+    try:
+        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
+    except subprocess.CalledProcessError:
+        log("请先安装 Nuitka: pip install nuitka", "ERROR")
+        sys.exit(1)
+
+    clean_build_dir()
+
+    setup(
+        name=PACKAGE_NAME,
+        version="1.2.202508190930",
+        description="Data Analysis Business Package (compiled, flat structure)",
+        author="Xie Zhou Yang",
+        packages=["algorithm"],                # 顶层包
+        package_dir={"": "."},
+        cmdclass={
+            "build_py": CustomBuildPy,
+            "bdist_wheel": CustomBdistWheel,
+        },
+        install_requires=INSTALL_REQUIRES,
+        zip_safe=False,
+    )

+ 52 - 148
dataAnalysisService/setup.py

@@ -1,160 +1,64 @@
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.install import install
+import compileall
 import os
 import sys
-import re
 import shutil
-import subprocess
-from setuptools import setup, find_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.bdist_wheel import bdist_wheel
-
-# ========== 配置 ==========
-PACKAGE_NAME = "dataAnalysisService"
-COMPILE_DIRS = ["service"]                # 需要编译的子目录(作为顶层包)
-# INSTALL_REQUIRES = ["dataAnalysisBusiness"]
-INSTALL_REQUIRES = []
-CLEAN_COMPILED_AFTER_BUILD = True
-# =========================
-
-def log(msg):
-    print(f"[SETUP] {msg}")
-
-def compile_with_nuitka(py_files):
-    for py_file in py_files:
-        if os.path.basename(py_file) == "__init__.py":
-            continue
-        log(f"编译: {py_file}")
+from pathlib import Path
 
-        output_dir = os.path.dirname(py_file)
-        cmd = [
-            sys.executable, "-m", "nuitka",
-            "--module",
-            "--no-pyi-file",
-            "--remove-output",
-            f"--output-dir={output_dir}",
-            py_file
-        ]
-        if sys.platform == "win32":
-            cmd.append("--mingw64")
-        result = subprocess.run(cmd, capture_output=True, text=True)
-        if result.returncode != 0:
-            log(f"编译失败: {py_file}\n{result.stderr}")
-            sys.exit(1)
-
-        base_name = os.path.splitext(os.path.basename(py_file))[0]
-        found = False
-        for ext in [".pyd", ".so"]:
-            pattern = re.escape(base_name) + r".*" + re.escape(ext)
-            for f in os.listdir(output_dir):
-                if re.match(pattern, f):
-                    src = os.path.join(output_dir, f)
-                    dst = os.path.join(output_dir, base_name + ext)
-                    shutil.move(src, dst)
-                    log(f"重命名: {src} -> {dst}")
-                    found = True
-                    break
-            if found:
-                break
-        if not found:
-            log(f"错误:未找到编译产物 {py_file}")
-            sys.exit(1)
-
-def clean_build_dir():
-    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
-    for d in dirs_to_clean:
-        if os.path.exists(d):
-            shutil.rmtree(d)
-            log(f"已删除: {d}")
+compileDirs=['service']
 
 class CustomBuildPy(build_py):
     def run(self):
-        src_root = os.getcwd()
-        log(f"源码根目录: {src_root}")
+        # 获取当前 Python 版本信息
+        py_version = f".cpython-{sys.version_info.major}{sys.version_info.minor}"
 
-        for compile_dir in COMPILE_DIRS:
-            target_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(target_dir):
-                log(f"警告: 目录不存在 {target_dir}")
-                continue
-            all_py = []
-            for root, _, files in os.walk(target_dir):
-                for file in files:
-                    if file.endswith(".py"):
-                        all_py.append(os.path.join(root, file))
-            if all_py:
-                compile_with_nuitka(all_py)
-            else:
-                log(f"在 {target_dir} 中没有找到 .py 文件")
+        for dir in compileDirs:
+            for root,_,subFiles in os.walk(dir):
+                compileall.compile_dir(root, force=True)
 
-        build_lib = self.build_lib
-        if not build_lib:
-            build_lib = os.path.join(src_root, "build", "lib")
+                for file in subFiles:
+                    if file.endswith('.pyc'):
+                        pyc_path = os.path.join(root, file)
+                        new_File = file.replace(py_version, '')
+                        new_path=os.path.join(Path(root).parent,new_File)
+                        shutil.move(pyc_path, new_path)
 
-        for compile_dir in COMPILE_DIRS:
-            src_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(src_dir):
-                continue
-            dst_dir = os.path.join(build_lib, compile_dir)
-            self.mkpath(dst_dir)
-            for root, _, files in os.walk(src_dir):
-                rel_path = os.path.relpath(root, src_dir)
-                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
-                self.mkpath(target_subdir)
-                for file in files:
-                    src_file = os.path.join(root, file)
-                    if file == "__init__.py":
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    elif file.endswith(".pyd") or file.endswith(".so"):
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
+        super().run()
 
-        if CLEAN_COMPILED_AFTER_BUILD:
-            for compile_dir in COMPILE_DIRS:
-                target_dir = os.path.join(src_root, compile_dir)
-                if not os.path.isdir(target_dir):
-                    continue
-                for root, _, files in os.walk(target_dir):
-                    for file in files:
-                        if file.endswith(".pyd") or file.endswith(".so"):
-                            os.remove(os.path.join(root, file))
-                            log(f"清理源码编译产物: {os.path.join(root, file)}")
-
-class CustomBdistWheel(bdist_wheel):
+class InstallCommand(install):
     def run(self):
-        self.run_command("build_py")
-        self.plat_name = self.get_platform()
-        bdist_wheel.run(self)
-
-    def get_platform(self):
-        if sys.platform == "win32":
-            return "win_amd64"
-        elif sys.platform == "linux":
-            return "linux_x86_64"
-        else:
-            return super().get_platform()
-
-if __name__ == "__main__":
-    try:
-        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
-    except subprocess.CalledProcessError:
-        log("请先安装 Nuitka: pip install nuitka", "ERROR")
-        sys.exit(1)
-
-    clean_build_dir()
-
-    setup(
-        name=PACKAGE_NAME,
-        version="1.2.202508190930",
-        description="Data Analysis Service Package (compiled, flat structure)",
-        author="Xie Zhou Yang",
-        packages=["service"],
-        package_dir={"": "."},
-        cmdclass={
-            "build_py": CustomBuildPy,
-            "bdist_wheel": CustomBdistWheel,
-        },
-        install_requires=INSTALL_REQUIRES,
-        zip_safe=False,
-    )
+        super().run()
+        # Remove all .py files from the installed package
+        # 若用于开发,可查看导入的自定义package 则注释本代码段
+        # 若用于部署交付,可应用本代码
+        # for root, _, files in os.walk(self.install_lib):
+        #     for file in files:
+        #         if file.endswith('.py'):
+        #             os.remove(os.path.join(root, file))
+
+setup(
+    name='dataAnalysisService',
+    version='1.2.202505131440',
+    description='Data Analysis Service Package',  # 描述信息
+    author='Xie Zhou Yang',  # 作者
+    packages=find_packages(),
+    cmdclass={
+        'build_py': CustomBuildPy,
+        'install': InstallCommand,
+    },
+    package_data={
+        'service': ['*.pyc']
+    },
+    exclude_package_data={'': ['*.py']}
+)
+
+# 获取 setup.py 所在的绝对路径
+setup_dir = os.path.abspath(os.path.dirname(__file__))
+# 编译打包后,删除pyc后缀文件
+for root, _, files in os.walk(setup_dir):
+    for file in files:
+        if file.endswith('.pyc') or file.endswith('.c'):
+            print(os.path.join(root, file))
+            os.remove(os.path.join(root, file))

+ 160 - 0
dataAnalysisService/setupModel.py

@@ -0,0 +1,160 @@
+import os
+import sys
+import re
+import shutil
+import subprocess
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.bdist_wheel import bdist_wheel
+
+# ========== 配置 ==========
+PACKAGE_NAME = "dataAnalysisService"
+COMPILE_DIRS = ["service"]                # 需要编译的子目录(作为顶层包)
+# INSTALL_REQUIRES = ["dataAnalysisBusiness"]
+INSTALL_REQUIRES = []
+CLEAN_COMPILED_AFTER_BUILD = True
+# =========================
+
+def log(msg):
+    print(f"[SETUP] {msg}")
+
+def compile_with_nuitka(py_files):
+    for py_file in py_files:
+        if os.path.basename(py_file) == "__init__.py":
+            continue
+        log(f"编译: {py_file}")
+
+        output_dir = os.path.dirname(py_file)
+        cmd = [
+            sys.executable, "-m", "nuitka",
+            "--module",
+            "--no-pyi-file",
+            "--remove-output",
+            f"--output-dir={output_dir}",
+            py_file
+        ]
+        if sys.platform == "win32":
+            cmd.append("--mingw64")
+        result = subprocess.run(cmd, capture_output=True, text=True)
+        if result.returncode != 0:
+            log(f"编译失败: {py_file}\n{result.stderr}")
+            sys.exit(1)
+
+        base_name = os.path.splitext(os.path.basename(py_file))[0]
+        found = False
+        for ext in [".pyd", ".so"]:
+            pattern = re.escape(base_name) + r".*" + re.escape(ext)
+            for f in os.listdir(output_dir):
+                if re.match(pattern, f):
+                    src = os.path.join(output_dir, f)
+                    dst = os.path.join(output_dir, base_name + ext)
+                    shutil.move(src, dst)
+                    log(f"重命名: {src} -> {dst}")
+                    found = True
+                    break
+            if found:
+                break
+        if not found:
+            log(f"错误:未找到编译产物 {py_file}")
+            sys.exit(1)
+
+def clean_build_dir():
+    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
+    for d in dirs_to_clean:
+        if os.path.exists(d):
+            shutil.rmtree(d)
+            log(f"已删除: {d}")
+
+class CustomBuildPy(build_py):
+    def run(self):
+        src_root = os.getcwd()
+        log(f"源码根目录: {src_root}")
+
+        for compile_dir in COMPILE_DIRS:
+            target_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(target_dir):
+                log(f"警告: 目录不存在 {target_dir}")
+                continue
+            all_py = []
+            for root, _, files in os.walk(target_dir):
+                for file in files:
+                    if file.endswith(".py"):
+                        all_py.append(os.path.join(root, file))
+            if all_py:
+                compile_with_nuitka(all_py)
+            else:
+                log(f"在 {target_dir} 中没有找到 .py 文件")
+
+        build_lib = self.build_lib
+        if not build_lib:
+            build_lib = os.path.join(src_root, "build", "lib")
+
+        for compile_dir in COMPILE_DIRS:
+            src_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(src_dir):
+                continue
+            dst_dir = os.path.join(build_lib, compile_dir)
+            self.mkpath(dst_dir)
+            for root, _, files in os.walk(src_dir):
+                rel_path = os.path.relpath(root, src_dir)
+                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
+                self.mkpath(target_subdir)
+                for file in files:
+                    src_file = os.path.join(root, file)
+                    if file == "__init__.py":
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    elif file.endswith(".pyd") or file.endswith(".so"):
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+
+        if CLEAN_COMPILED_AFTER_BUILD:
+            for compile_dir in COMPILE_DIRS:
+                target_dir = os.path.join(src_root, compile_dir)
+                if not os.path.isdir(target_dir):
+                    continue
+                for root, _, files in os.walk(target_dir):
+                    for file in files:
+                        if file.endswith(".pyd") or file.endswith(".so"):
+                            os.remove(os.path.join(root, file))
+                            log(f"清理源码编译产物: {os.path.join(root, file)}")
+
+class CustomBdistWheel(bdist_wheel):
+    def run(self):
+        self.run_command("build_py")
+        self.plat_name = self.get_platform()
+        bdist_wheel.run(self)
+
+    def get_platform(self):
+        if sys.platform == "win32":
+            return "win_amd64"
+        elif sys.platform == "linux":
+            return "linux_x86_64"
+        else:
+            return super().get_platform()
+
+if __name__ == "__main__":
+    try:
+        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
+    except subprocess.CalledProcessError:
+        log("请先安装 Nuitka: pip install nuitka", "ERROR")
+        sys.exit(1)
+
+    clean_build_dir()
+
+    setup(
+        name=PACKAGE_NAME,
+        version="1.2.202508190930",
+        description="Data Analysis Service Package (compiled, flat structure)",
+        author="Xie Zhou Yang",
+        packages=["service"],
+        package_dir={"": "."},
+        cmdclass={
+            "build_py": CustomBuildPy,
+            "bdist_wheel": CustomBdistWheel,
+        },
+        install_requires=INSTALL_REQUIRES,
+        zip_safe=False,
+    )

+ 52 - 148
dataContract/setup.py

@@ -1,160 +1,64 @@
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.install import install
+import compileall
 import os
 import sys
-import re
 import shutil
-import subprocess
-from setuptools import setup, find_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.bdist_wheel import bdist_wheel
-
-# ========== 配置 ==========
-PACKAGE_NAME = "dataContract"
-COMPILE_DIRS = ["algorithmContract"]     # 需要编译的子目录(作为顶层包)
-# INSTALL_REQUIRES = ["repositoryZN"]
-INSTALL_REQUIRES = []
-CLEAN_COMPILED_AFTER_BUILD = True
-# =========================
-
-def log(msg):
-    print(f"[SETUP] {msg}")
-
-def compile_with_nuitka(py_files):
-    for py_file in py_files:
-        if os.path.basename(py_file) == "__init__.py":
-            continue
-        log(f"编译: {py_file}")
+from pathlib import Path
 
-        output_dir = os.path.dirname(py_file)
-        cmd = [
-            sys.executable, "-m", "nuitka",
-            "--module",
-            "--no-pyi-file",
-            "--remove-output",
-            f"--output-dir={output_dir}",
-            py_file
-        ]
-        if sys.platform == "win32":
-            cmd.append("--mingw64")
-        result = subprocess.run(cmd, capture_output=True, text=True)
-        if result.returncode != 0:
-            log(f"编译失败: {py_file}\n{result.stderr}")
-            sys.exit(1)
-
-        base_name = os.path.splitext(os.path.basename(py_file))[0]
-        found = False
-        for ext in [".pyd", ".so"]:
-            pattern = re.escape(base_name) + r".*" + re.escape(ext)
-            for f in os.listdir(output_dir):
-                if re.match(pattern, f):
-                    src = os.path.join(output_dir, f)
-                    dst = os.path.join(output_dir, base_name + ext)
-                    shutil.move(src, dst)
-                    log(f"重命名: {src} -> {dst}")
-                    found = True
-                    break
-            if found:
-                break
-        if not found:
-            log(f"错误:未找到编译产物 {py_file}")
-            sys.exit(1)
-
-def clean_build_dir():
-    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
-    for d in dirs_to_clean:
-        if os.path.exists(d):
-            shutil.rmtree(d)
-            log(f"已删除: {d}")
+compileDirs=['algorithmContract']
 
 class CustomBuildPy(build_py):
     def run(self):
-        src_root = os.getcwd()
-        log(f"源码根目录: {src_root}")
+        # 获取当前 Python 版本信息
+        py_version = f".cpython-{sys.version_info.major}{sys.version_info.minor}"
 
-        for compile_dir in COMPILE_DIRS:
-            target_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(target_dir):
-                log(f"警告: 目录不存在 {target_dir}")
-                continue
-            all_py = []
-            for root, _, files in os.walk(target_dir):
-                for file in files:
-                    if file.endswith(".py"):
-                        all_py.append(os.path.join(root, file))
-            if all_py:
-                compile_with_nuitka(all_py)
-            else:
-                log(f"在 {target_dir} 中没有找到 .py 文件")
+        for dir in compileDirs:
+            for root,_,subFiles in os.walk(dir):
+                compileall.compile_dir(root, force=True)
 
-        build_lib = self.build_lib
-        if not build_lib:
-            build_lib = os.path.join(src_root, "build", "lib")
+                for file in subFiles:
+                    if file.endswith('.pyc'):
+                        pyc_path = os.path.join(root, file)
+                        new_File = file.replace(py_version, '')
+                        new_path=os.path.join(Path(root).parent,new_File)
+                        shutil.move(pyc_path, new_path)
 
-        for compile_dir in COMPILE_DIRS:
-            src_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(src_dir):
-                continue
-            dst_dir = os.path.join(build_lib, compile_dir)
-            self.mkpath(dst_dir)
-            for root, _, files in os.walk(src_dir):
-                rel_path = os.path.relpath(root, src_dir)
-                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
-                self.mkpath(target_subdir)
-                for file in files:
-                    src_file = os.path.join(root, file)
-                    if file == "__init__.py":
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    elif file.endswith(".pyd") or file.endswith(".so"):
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
+        super().run()
 
-        if CLEAN_COMPILED_AFTER_BUILD:
-            for compile_dir in COMPILE_DIRS:
-                target_dir = os.path.join(src_root, compile_dir)
-                if not os.path.isdir(target_dir):
-                    continue
-                for root, _, files in os.walk(target_dir):
-                    for file in files:
-                        if file.endswith(".pyd") or file.endswith(".so"):
-                            os.remove(os.path.join(root, file))
-                            log(f"清理源码编译产物: {os.path.join(root, file)}")
-
-class CustomBdistWheel(bdist_wheel):
+class InstallCommand(install):
     def run(self):
-        self.run_command("build_py")
-        self.plat_name = self.get_platform()
-        bdist_wheel.run(self)
-
-    def get_platform(self):
-        if sys.platform == "win32":
-            return "win_amd64"
-        elif sys.platform == "linux":
-            return "linux_x86_64"
-        else:
-            return super().get_platform()
-
-if __name__ == "__main__":
-    try:
-        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
-    except subprocess.CalledProcessError:
-        log("请先安装 Nuitka: pip install nuitka", "ERROR")
-        sys.exit(1)
-
-    clean_build_dir()
-
-    setup(
-        name=PACKAGE_NAME,
-        version="1.0.202508190930",
-        description="Data Contract Package (compiled, flat structure)",
-        author="Xie Zhou Yang",
-        packages=["algorithmContract"],
-        package_dir={"": "."},
-        cmdclass={
-            "build_py": CustomBuildPy,
-            "bdist_wheel": CustomBdistWheel,
-        },
-        install_requires=INSTALL_REQUIRES,
-        zip_safe=False,
-    )
+        super().run()
+        # Remove all .py files from the installed package
+        # 若用于开发,可查看导入的自定义package 则注释本代码段
+        # 若用于部署交付,可应用本代码
+        # for root, _, files in os.walk(self.install_lib):
+        #     for file in files:
+        #         if file.endswith('.py'):
+        #             os.remove(os.path.join(root, file))
+
+setup(
+    name='dataContract',
+    version='1.2.202505131440',
+    description='Data Contract Package', # 描述信息
+    author='Xie Zhou Yang', # 作者
+    packages=find_packages(),
+    cmdclass={
+        'build_py': CustomBuildPy,
+        'install': InstallCommand,
+    },
+    package_data={
+        'algorithmContract': ['*.pyc']
+    },
+    exclude_package_data={'': ['*.py']}
+)
+
+# 获取 setup.py 所在的绝对路径
+setup_dir = os.path.abspath(os.path.dirname(__file__))
+# 编译打包后,删除pyc后缀文件
+for root, _, files in os.walk(setup_dir):
+    for file in files:
+        if file.endswith('.pyc') or file.endswith('.c'):
+            print(os.path.join(root, file))
+            os.remove(os.path.join(root, file))

+ 160 - 0
dataContract/setupModel.py

@@ -0,0 +1,160 @@
+import os
+import sys
+import re
+import shutil
+import subprocess
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.bdist_wheel import bdist_wheel
+
+# ========== 配置 ==========
+PACKAGE_NAME = "dataContract"
+COMPILE_DIRS = ["algorithmContract"]     # 需要编译的子目录(作为顶层包)
+# INSTALL_REQUIRES = ["repositoryZN"]
+INSTALL_REQUIRES = []
+CLEAN_COMPILED_AFTER_BUILD = True
+# =========================
+
+def log(msg):
+    print(f"[SETUP] {msg}")
+
+def compile_with_nuitka(py_files):
+    for py_file in py_files:
+        if os.path.basename(py_file) == "__init__.py":
+            continue
+        log(f"编译: {py_file}")
+
+        output_dir = os.path.dirname(py_file)
+        cmd = [
+            sys.executable, "-m", "nuitka",
+            "--module",
+            "--no-pyi-file",
+            "--remove-output",
+            f"--output-dir={output_dir}",
+            py_file
+        ]
+        if sys.platform == "win32":
+            cmd.append("--mingw64")
+        result = subprocess.run(cmd, capture_output=True, text=True)
+        if result.returncode != 0:
+            log(f"编译失败: {py_file}\n{result.stderr}")
+            sys.exit(1)
+
+        base_name = os.path.splitext(os.path.basename(py_file))[0]
+        found = False
+        for ext in [".pyd", ".so"]:
+            pattern = re.escape(base_name) + r".*" + re.escape(ext)
+            for f in os.listdir(output_dir):
+                if re.match(pattern, f):
+                    src = os.path.join(output_dir, f)
+                    dst = os.path.join(output_dir, base_name + ext)
+                    shutil.move(src, dst)
+                    log(f"重命名: {src} -> {dst}")
+                    found = True
+                    break
+            if found:
+                break
+        if not found:
+            log(f"错误:未找到编译产物 {py_file}")
+            sys.exit(1)
+
+def clean_build_dir():
+    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
+    for d in dirs_to_clean:
+        if os.path.exists(d):
+            shutil.rmtree(d)
+            log(f"已删除: {d}")
+
+class CustomBuildPy(build_py):
+    def run(self):
+        src_root = os.getcwd()
+        log(f"源码根目录: {src_root}")
+
+        for compile_dir in COMPILE_DIRS:
+            target_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(target_dir):
+                log(f"警告: 目录不存在 {target_dir}")
+                continue
+            all_py = []
+            for root, _, files in os.walk(target_dir):
+                for file in files:
+                    if file.endswith(".py"):
+                        all_py.append(os.path.join(root, file))
+            if all_py:
+                compile_with_nuitka(all_py)
+            else:
+                log(f"在 {target_dir} 中没有找到 .py 文件")
+
+        build_lib = self.build_lib
+        if not build_lib:
+            build_lib = os.path.join(src_root, "build", "lib")
+
+        for compile_dir in COMPILE_DIRS:
+            src_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(src_dir):
+                continue
+            dst_dir = os.path.join(build_lib, compile_dir)
+            self.mkpath(dst_dir)
+            for root, _, files in os.walk(src_dir):
+                rel_path = os.path.relpath(root, src_dir)
+                target_subdir = os.path.join(dst_dir, rel_path) if rel_path != '.' else dst_dir
+                self.mkpath(target_subdir)
+                for file in files:
+                    src_file = os.path.join(root, file)
+                    if file == "__init__.py":
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    elif file.endswith(".pyd") or file.endswith(".so"):
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+
+        if CLEAN_COMPILED_AFTER_BUILD:
+            for compile_dir in COMPILE_DIRS:
+                target_dir = os.path.join(src_root, compile_dir)
+                if not os.path.isdir(target_dir):
+                    continue
+                for root, _, files in os.walk(target_dir):
+                    for file in files:
+                        if file.endswith(".pyd") or file.endswith(".so"):
+                            os.remove(os.path.join(root, file))
+                            log(f"清理源码编译产物: {os.path.join(root, file)}")
+
+class CustomBdistWheel(bdist_wheel):
+    def run(self):
+        self.run_command("build_py")
+        self.plat_name = self.get_platform()
+        bdist_wheel.run(self)
+
+    def get_platform(self):
+        if sys.platform == "win32":
+            return "win_amd64"
+        elif sys.platform == "linux":
+            return "linux_x86_64"
+        else:
+            return super().get_platform()
+
+if __name__ == "__main__":
+    try:
+        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
+    except subprocess.CalledProcessError:
+        log("请先安装 Nuitka: pip install nuitka", "ERROR")
+        sys.exit(1)
+
+    clean_build_dir()
+
+    setup(
+        name=PACKAGE_NAME,
+        version="1.0.202508190930",
+        description="Data Contract Package (compiled, flat structure)",
+        author="Xie Zhou Yang",
+        packages=["algorithmContract"],
+        package_dir={"": "."},
+        cmdclass={
+            "build_py": CustomBuildPy,
+            "bdist_wheel": CustomBdistWheel,
+        },
+        install_requires=INSTALL_REQUIRES,
+        zip_safe=False,
+    )

+ 54 - 180
repositoryZN/setup.py

@@ -1,192 +1,66 @@
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.install import install
+import compileall
 import os
 import sys
-import re
 import shutil
-import subprocess
-from setuptools import setup, find_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.bdist_wheel import bdist_wheel
-
-# ========== 配置 ==========
-PACKAGE_NAME = "repositoryZN"
-COMPILE_DIRS = ["utils"]           # 编译 utils 目录和根目录下的 .py
-INSTALL_REQUIRES = []                   # 无内部依赖
-CLEAN_COMPILED_AFTER_BUILD = True
-# =========================
-
-def log(msg):
-    print(f"[SETUP] {msg}")
-
-def compile_with_nuitka(py_files):
-    for py_file in py_files:
-        if os.path.basename(py_file) == "__init__.py":
-            continue
-        log(f"编译: {py_file}")
-
-        output_dir = os.path.dirname(py_file)
-        cmd = [
-            sys.executable, "-m", "nuitka",
-            "--module",
-            "--no-pyi-file",
-            "--remove-output",
-            f"--output-dir={output_dir}",
-            py_file
-        ]
-        if sys.platform == "win32":
-            cmd.append("--mingw64")
-        result = subprocess.run(cmd, capture_output=True, text=True)
-        if result.returncode != 0:
-            log(f"编译失败: {py_file}\n{result.stderr}")
-            sys.exit(1)
+from pathlib import Path
 
-        base_name = os.path.splitext(os.path.basename(py_file))[0]
-        found = False
-        for ext in [".pyd", ".so"]:
-            pattern = re.escape(base_name) + r".*" + re.escape(ext)
-            for f in os.listdir(output_dir):
-                if re.match(pattern, f):
-                    src = os.path.join(output_dir, f)
-                    dst = os.path.join(output_dir, base_name + ext)
-                    shutil.move(src, dst)
-                    log(f"重命名: {src} -> {dst}")
-                    found = True
-                    break
-            if found:
-                break
-        if not found:
-            log(f"错误:未找到编译产物 {py_file}")
-            sys.exit(1)
-
-def clean_build_dir():
-    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
-    for d in dirs_to_clean:
-        if os.path.exists(d):
-            shutil.rmtree(d)
-            log(f"已删除: {d}")
+compileDirs=['utils']
 
 class CustomBuildPy(build_py):
     def run(self):
-        src_root = os.getcwd()
-        log(f"源码根目录: {src_root}")
-
-        # 1. 编译所有需要编译的目录(包括根目录 ".")
-        for compile_dir in COMPILE_DIRS:
-            if compile_dir == ".":
-                target_dir = src_root
-            else:
-                target_dir = os.path.join(src_root, compile_dir)
-            if not os.path.isdir(target_dir):
-                log(f"警告: 目录不存在 {target_dir}")
-                continue
-            all_py = []
-            for root, _, files in os.walk(target_dir):
-                for file in files:
-                    if file.endswith(".py"):
-                        all_py.append(os.path.join(root, file))
-            if all_py:
-                compile_with_nuitka(all_py)
-            else:
-                log(f"在 {target_dir} 中没有找到 .py 文件")
+        # 获取当前 Python 版本信息
+        py_version = f".cpython-{sys.version_info.major}{sys.version_info.minor}"
 
-        # 2. 手动复制:对于 utils 目录作为顶级包,对于根目录下的文件直接复制到 build/lib 根目录
-        build_lib = self.build_lib
-        if not build_lib:
-            build_lib = os.path.join(src_root, "build", "lib")
+        for dir in compileDirs:
+            for root,_,subFiles in os.walk(dir):
+                compileall.compile_dir(root, force=True)
 
-        # 处理 utils 目录(作为包)
-        utils_src = os.path.join(src_root, "utils")
-        if os.path.isdir(utils_src):
-            utils_dst = os.path.join(build_lib, "utils")
-            self.mkpath(utils_dst)
-            for root, _, files in os.walk(utils_src):
-                rel_path = os.path.relpath(root, utils_src)
-                target_subdir = os.path.join(utils_dst, rel_path) if rel_path != '.' else utils_dst
-                self.mkpath(target_subdir)
-                for file in files:
-                    src_file = os.path.join(root, file)
-                    if file == "__init__.py":
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
-                    elif file.endswith(".pyd") or file.endswith(".so"):
-                        dst_file = os.path.join(target_subdir, file)
-                        self.copy_file(src_file, dst_file)
-                        log(f"复制 {src_file} -> {dst_file}")
+                for file in subFiles:
+                    if file.endswith('.pyc'):
+                        pyc_path = os.path.join(root, file)
+                        new_File = file.replace(py_version, '')
+                        new_path=os.path.join(Path(root).parent,new_File)
+                        shutil.move(pyc_path, new_path)
 
-        # 处理根目录下的文件(作为顶级模块,直接放在 build/lib 根目录)
-        for file in os.listdir(src_root):
-            if file.endswith(".pyd") or file.endswith(".so"):
-                src_file = os.path.join(src_root, file)
-                dst_file = os.path.join(build_lib, file)
-                self.copy_file(src_file, dst_file)
-                log(f"复制根模块 {src_file} -> {dst_file}")
-            elif file == "__init__.py":
-                # 如果根目录有 __init__.py,也复制(让根目录本身成为一个包)
-                src_file = os.path.join(src_root, file)
-                dst_file = os.path.join(build_lib, file)
-                self.copy_file(src_file, dst_file)
-                log(f"复制根 __init__.py {src_file} -> {dst_file}")
+        super().run()
 
-        # 3. 清理源码目录中的 .pyd/.so
-        if CLEAN_COMPILED_AFTER_BUILD:
-            for compile_dir in COMPILE_DIRS:
-                if compile_dir == ".":
-                    target_dir = src_root
-                else:
-                    target_dir = os.path.join(src_root, compile_dir)
-                if not os.path.isdir(target_dir):
-                    continue
-                for root, _, files in os.walk(target_dir):
-                    for file in files:
-                        if file.endswith(".pyd") or file.endswith(".so"):
-                            os.remove(os.path.join(root, file))
-                            log(f"清理源码编译产物: {os.path.join(root, file)}")
-
-class CustomBdistWheel(bdist_wheel):
+class InstallCommand(install):
     def run(self):
-        self.run_command("build_py")
-        self.plat_name = self.get_platform()
-        bdist_wheel.run(self)
-
-    def get_platform(self):
-        if sys.platform == "win32":
-            return "win_amd64"
-        elif sys.platform == "linux":
-            return "linux_x86_64"
-        else:
-            return super().get_platform()
-
-if __name__ == "__main__":
-    try:
-        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
-    except subprocess.CalledProcessError:
-        log("请先安装 Nuitka: pip install nuitka", "ERROR")
-        sys.exit(1)
-
-    clean_build_dir()
-
-    # 动态确定要安装的包和模块
-    packages = []
-    if os.path.isdir("utils"):
-        packages.append("utils")
-    # 根目录下的顶级模块(如果存在这些 .py 文件,它们会被编译成 .pyd 并安装)
-    py_modules = []
-    for mod in ["jsonUtil", "logUtil", "csvFileUtil"]:
-        if os.path.exists(f"{mod}.py"):
-            py_modules.append(mod)
-
-    setup(
-        name=PACKAGE_NAME,
-        version="1.0.202508190930",
-        description="Repository ZN Package (compiled, flat structure)",
-        author="Xie Zhou Yang",
-        packages=packages,
-        py_modules=py_modules,
-        package_dir={"": "."},
-        cmdclass={
-            "build_py": CustomBuildPy,
-            "bdist_wheel": CustomBdistWheel,
-        },
-        install_requires=INSTALL_REQUIRES,
-        zip_safe=False,
-    )
+        super().run()
+        # Remove all .py files from the installed package
+        # 若用于开发,可查看导入的自定义package 则注释本代码段
+        # 若用于部署交付,可应用本代码
+        # for root, _, files in os.walk(self.install_lib):
+        #     for file in files:
+        #         if file.endswith('.py'):
+        #             os.remove(os.path.join(root, file))
+
+setup(
+    name='repositoryZN',
+    version='1.2.202505131440',
+    description='Repository Package', # 描述信息
+    author='Xie Zhou Yang', # 作者
+    packages=find_packages(),
+    cmdclass={
+        'build_py': CustomBuildPy,
+        'install': InstallCommand,
+    },
+    package_data={
+        'utils': ['*.pyc'],
+        'utils.minioUtil': ['*.pyc'],
+        'utils.rdbmsUtil': ['*.pyc']
+    },
+    exclude_package_data={'': ['*.py']}
+)
+
+# 获取 setup.py 所在的绝对路径
+setup_dir = os.path.abspath(os.path.dirname(__file__))
+# 编译打包后,删除pyc后缀文件
+for root, _, files in os.walk(setup_dir):
+    for file in files:
+        if file.endswith('.pyc') or file.endswith('.c'):
+            print(os.path.join(root, file))
+            os.remove(os.path.join(root, file))

+ 192 - 0
repositoryZN/setupModel.py

@@ -0,0 +1,192 @@
+import os
+import sys
+import re
+import shutil
+import subprocess
+from setuptools import setup, find_packages
+from setuptools.command.build_py import build_py
+from setuptools.command.bdist_wheel import bdist_wheel
+
+# ========== 配置 ==========
+PACKAGE_NAME = "repositoryZN"
+COMPILE_DIRS = ["utils"]           # 编译 utils 目录和根目录下的 .py
+INSTALL_REQUIRES = []                   # 无内部依赖
+CLEAN_COMPILED_AFTER_BUILD = True
+# =========================
+
+def log(msg):
+    print(f"[SETUP] {msg}")
+
+def compile_with_nuitka(py_files):
+    for py_file in py_files:
+        if os.path.basename(py_file) == "__init__.py":
+            continue
+        log(f"编译: {py_file}")
+
+        output_dir = os.path.dirname(py_file)
+        cmd = [
+            sys.executable, "-m", "nuitka",
+            "--module",
+            "--no-pyi-file",
+            "--remove-output",
+            f"--output-dir={output_dir}",
+            py_file
+        ]
+        if sys.platform == "win32":
+            cmd.append("--mingw64")
+        result = subprocess.run(cmd, capture_output=True, text=True)
+        if result.returncode != 0:
+            log(f"编译失败: {py_file}\n{result.stderr}")
+            sys.exit(1)
+
+        base_name = os.path.splitext(os.path.basename(py_file))[0]
+        found = False
+        for ext in [".pyd", ".so"]:
+            pattern = re.escape(base_name) + r".*" + re.escape(ext)
+            for f in os.listdir(output_dir):
+                if re.match(pattern, f):
+                    src = os.path.join(output_dir, f)
+                    dst = os.path.join(output_dir, base_name + ext)
+                    shutil.move(src, dst)
+                    log(f"重命名: {src} -> {dst}")
+                    found = True
+                    break
+            if found:
+                break
+        if not found:
+            log(f"错误:未找到编译产物 {py_file}")
+            sys.exit(1)
+
+def clean_build_dir():
+    dirs_to_clean = ["build", f"{PACKAGE_NAME}.egg-info"]
+    for d in dirs_to_clean:
+        if os.path.exists(d):
+            shutil.rmtree(d)
+            log(f"已删除: {d}")
+
+class CustomBuildPy(build_py):
+    def run(self):
+        src_root = os.getcwd()
+        log(f"源码根目录: {src_root}")
+
+        # 1. 编译所有需要编译的目录(包括根目录 ".")
+        for compile_dir in COMPILE_DIRS:
+            if compile_dir == ".":
+                target_dir = src_root
+            else:
+                target_dir = os.path.join(src_root, compile_dir)
+            if not os.path.isdir(target_dir):
+                log(f"警告: 目录不存在 {target_dir}")
+                continue
+            all_py = []
+            for root, _, files in os.walk(target_dir):
+                for file in files:
+                    if file.endswith(".py"):
+                        all_py.append(os.path.join(root, file))
+            if all_py:
+                compile_with_nuitka(all_py)
+            else:
+                log(f"在 {target_dir} 中没有找到 .py 文件")
+
+        # 2. 手动复制:对于 utils 目录作为顶级包,对于根目录下的文件直接复制到 build/lib 根目录
+        build_lib = self.build_lib
+        if not build_lib:
+            build_lib = os.path.join(src_root, "build", "lib")
+
+        # 处理 utils 目录(作为包)
+        utils_src = os.path.join(src_root, "utils")
+        if os.path.isdir(utils_src):
+            utils_dst = os.path.join(build_lib, "utils")
+            self.mkpath(utils_dst)
+            for root, _, files in os.walk(utils_src):
+                rel_path = os.path.relpath(root, utils_src)
+                target_subdir = os.path.join(utils_dst, rel_path) if rel_path != '.' else utils_dst
+                self.mkpath(target_subdir)
+                for file in files:
+                    src_file = os.path.join(root, file)
+                    if file == "__init__.py":
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+                    elif file.endswith(".pyd") or file.endswith(".so"):
+                        dst_file = os.path.join(target_subdir, file)
+                        self.copy_file(src_file, dst_file)
+                        log(f"复制 {src_file} -> {dst_file}")
+
+        # 处理根目录下的文件(作为顶级模块,直接放在 build/lib 根目录)
+        for file in os.listdir(src_root):
+            if file.endswith(".pyd") or file.endswith(".so"):
+                src_file = os.path.join(src_root, file)
+                dst_file = os.path.join(build_lib, file)
+                self.copy_file(src_file, dst_file)
+                log(f"复制根模块 {src_file} -> {dst_file}")
+            elif file == "__init__.py":
+                # 如果根目录有 __init__.py,也复制(让根目录本身成为一个包)
+                src_file = os.path.join(src_root, file)
+                dst_file = os.path.join(build_lib, file)
+                self.copy_file(src_file, dst_file)
+                log(f"复制根 __init__.py {src_file} -> {dst_file}")
+
+        # 3. 清理源码目录中的 .pyd/.so
+        if CLEAN_COMPILED_AFTER_BUILD:
+            for compile_dir in COMPILE_DIRS:
+                if compile_dir == ".":
+                    target_dir = src_root
+                else:
+                    target_dir = os.path.join(src_root, compile_dir)
+                if not os.path.isdir(target_dir):
+                    continue
+                for root, _, files in os.walk(target_dir):
+                    for file in files:
+                        if file.endswith(".pyd") or file.endswith(".so"):
+                            os.remove(os.path.join(root, file))
+                            log(f"清理源码编译产物: {os.path.join(root, file)}")
+
+class CustomBdistWheel(bdist_wheel):
+    def run(self):
+        self.run_command("build_py")
+        self.plat_name = self.get_platform()
+        bdist_wheel.run(self)
+
+    def get_platform(self):
+        if sys.platform == "win32":
+            return "win_amd64"
+        elif sys.platform == "linux":
+            return "linux_x86_64"
+        else:
+            return super().get_platform()
+
+if __name__ == "__main__":
+    try:
+        subprocess.run([sys.executable, "-m", "nuitka", "--version"], capture_output=True, check=True)
+    except subprocess.CalledProcessError:
+        log("请先安装 Nuitka: pip install nuitka", "ERROR")
+        sys.exit(1)
+
+    clean_build_dir()
+
+    # 动态确定要安装的包和模块
+    packages = []
+    if os.path.isdir("utils"):
+        packages.append("utils")
+    # 根目录下的顶级模块(如果存在这些 .py 文件,它们会被编译成 .pyd 并安装)
+    py_modules = []
+    for mod in ["jsonUtil", "logUtil", "csvFileUtil"]:
+        if os.path.exists(f"{mod}.py"):
+            py_modules.append(mod)
+
+    setup(
+        name=PACKAGE_NAME,
+        version="1.0.202508190930",
+        description="Repository ZN Package (compiled, flat structure)",
+        author="Xie Zhou Yang",
+        packages=packages,
+        py_modules=py_modules,
+        package_dir={"": "."},
+        cmdclass={
+            "build_py": CustomBuildPy,
+            "bdist_wheel": CustomBdistWheel,
+        },
+        install_requires=INSTALL_REQUIRES,
+        zip_safe=False,
+    )