【python源码加密】Cython针对python工程多层级目录处理办法

上一篇介绍了【python源码加密】Cython方案讲解及简单示例,这篇着重介绍,对于python工程的多级目录如何进行Cython编译以及使用(文章末尾有获取源码方式)

Cython编译的问题

不支持同名文件:Cython编译的时候,同名文件只能打包一个pyd,那就必须一个文件夹一个文件夹的编译

  • 不支持package:由于同名问题,而python在识别package的时候靠的是__init__.py
  • 不支持原地生成:python setup.py build_ext --inplace 生成的pyd文件都在同个目录下
  • 路径不能过长,路径过程容易出错

解决办法

我们可以通过一些逻辑制作一个打包脚本,用来解决以上的问题,脚本的逻辑如下:

  1. 将需要打包的整个源目录整个复制出来,形成目标目录
  2. 除了__init__.py外,编译其他的 .py文件,使用命令 cythonize -i xx.py
  3. 清理掉所有的中间文件以及除了__init__.py外的.py源码文件
  4. 将目标文件夹改名成源文件夹就可以使用了

示例

我的源码工程目录结构如下:

.
└── cython_module_2
    ├── f2
    │   ├── f2_1
    │   │   ├── fun2_1.py
    │   │   └── __init__.py
    │   ├── fun21.py
    │   ├── fun22.py
    │   └── __init__.py
    ├── f3
    │   ├── fun31.py
    │   └── __init__.py
    ├── f.py
    └── __init__.py

通过编写pack_cpython.py脚本完成对该目录cython_module_2的cython编译:

# -*- coding: UTF-8 -*-
import shutil
import sys
import os
import subprocess

def clearzj(path):
    files = os.listdir(path)
    for fd in files:
        cur_path = os.path.join(path, fd)
        if os.path.isdir(cur_path):
            if fd == '__pycache__' or fd == 'build':
                shutil.rmtree(cur_path)
            else:
                clearzj(cur_path)
        else:
            _, ext = os.path.splitext(cur_path)
            if ext == '.c' or ext == '.py':
                if '__init__' not in cur_path:
                    os.remove(cur_path)
                

# 获取文件夹下所有的.py文件, 文件夹可以是多层级的
def find_py_files(folder):
    py_files = []
    for item in os.listdir(folder):
        item_path = os.path.join(folder, item)
        if os.path.isfile(item_path):
            if item.endswith('.py'):
                py_files.append(item_path)
        elif os.path.isdir(item_path):
            py_files.extend(find_py_files(item_path))
    return py_files

def pack_cython(src_path, dest_path):
    # 1. 将需要打包的整个源目录整个复制出来,形成目标目录
    if os.path.exists(dest_path):
        shutil.rmtree(dest_path)
    if os.path.exists(src_path):
        shutil.copytree(src_path, dest_path)
    if os.path.exists(dest_path) is False:
        print(f'目标文件夹={dest_path}不存在!')
        return
    # 2. 除了__init__.py外,编译其他的 .py文件
    py_files = find_py_files(dest_path)
    for py in py_files:
        if '__init__' not in py:
            cmd = ["cythonize", "-i", py]
            try:
                subprocess.run(cmd, check=True)
            except subprocess.CalledProcessError as e:
                print("Cython编译失败:", e)
                sys.exit(0)
    # 3. 清理掉所有的中间文件以及除了__init__.py外的.py源码文件
    clearzj(dest_path)
    # 4. 将目标文件夹改名成源文件夹就可以使用了

if __name__ == "__main__":
    src_folder = './cython_module_2'
    dest_folder = f'{src_folder}_back'
    pack_cython(src_folder, dest_folder)

执行 python pack_cython.py,完成编译,过程如下(windows和linux均可):
在这里插入图片描述
此时,编译完成后的目录如下:
在这里插入图片描述
我们直接对该包进行调用即可:
在这里插入图片描述
结束语

由于本人能力有限,难免有疏漏之处

文中源码文件【获取方式】:关注公众号:利哥AI实例探险

给公众号发送 cython打包示例1 获取下载方式,免费,无套路,关注即可!!!

利哥AI实例探险

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值