目录
1、Cython批量编译py文件
2、生成whl文件
3、关于使用报错找不到模块
Cython是一个编程语言,它通过类似Python的语法来编写C扩展并可以被Python调用。能够将Python+C混合编码的.pyx脚本转换为C代码,主要用于优化Python脚本性能或Python调用C函数库。基于它的原理,可以得到一种代码加密的思路:将 .py/.pyx 编译为 .c 文件,再将 .c 文件编译为 .so(Unix) 或 .pyd(Windows),这样得到的文件更难反编译。
优点
不足
批量加密代码:
from setuptools import setup, find_packages
from Cython.Build import cythonize
import os
def print_files(path):
'''
循环遍历文件夹与文件
:param path: 路径
:return:
'''
for root, dirs, files in os.walk(path):
for file in files:
print(os.path.join(root, file)) # 打印完整路径
print(file) # 打印文件名
print(os.path.splitext(file)[0]) # 打印无扩展名的文件名
filepaths = []
def encrypt_py(path):
'''
加密路径下除了__init__.py的所有.py文件
:param path:路径
:return:
'''
for root, dirs, files in os.walk(path):
for file in files:
fullpath = os.path.join(root, file)
print(fullpath) # 打印完整路径
filepath = file
print(filepath) # 打印文件名
filename = os.path.splitext(file)[0]
print(filename) # 打印无扩展名的文件名
if filename == "__init__":
continue
suffix = os.path.splitext(file)[1].split('.')[-1]
print(suffix)
if suffix == "py":
filepaths.append(fullpath)
encrypt_py(".\\autoTestPrj")
print(filepaths)
for f in filepaths:
setup(ext_modules=cythonize(f))
使用以下命令在setup.py目录下执行:
python setup.py build_ext --inplace
build_ext参数是一个命令,指示distutils构建扩展对象或cythonize调用创建的对象。 可选的--inplace标志指示distutils将每个扩展模块放在其各自的Cython .pyx源文件旁边
注意:__init__.py不要加密,加密后打包为whl再安装无法识别到__init__.py,不会安装目录下的pyd文件!!
如果直接打包,会把没有加密过的源码也打包进去,安装时会一同安装,那加密就没有意义了。所以可以先移除.py文件,再打包。
代码如下:
from setuptools import setup, find_packages
setup(name='autoTestPrjencrypt', #打包的名字最好不要有"-""_"等特殊字符,测试的时候发现有特殊字符可能存在找不到该模块的问题
version='1.0.1',
description='aaaaaa',
author='aaaaaa',
author_email='[email protected]',
packages=find_packages(),
include_package_data=True,
# 将pyd文件打包进入
package_data={
'': ['*.pyd'],
},
)
在cmd执行以下命令:
python setup.py bdist_wheel
打包完成后可以在dist文件下看到whl文件:
此时再进行安装:
pip install autoTestPrjencrypt-1.0.1-py3-none-any.whl
安装完成可以输入:
pip show package_name
如果安装成功可以看到输出的包的信息和安装位置:
此时使用可能会提示找不到该模块
解决1:
我们可以打包前把.pyd名称去掉生成时生成的“.cp39-win_amd64”这一串字符,然后再执行步骤2,安装好后就可以正常使用了
解决2:
我的模块层次是这样的:
[项目文件夹]
│ globals.py
│ __init__.py
│
├─ocr
│ │ __init__.py
│ └─ imgtotxt.py
│
├─res
├─tests
│ └─__init__.py
│
└──tool
│ __init__.py
└─ timetool.py
在orc/imgtotxt.py中我调用了tool/timetool.py中的函数,安装好之后报错找不到orc/imgtotxt.py导入tool/timetool.py的模块。
因为在imgtotxt.py中导入是这样写的,安装后找不到tool模块就会报错:
from tool.timetool import get_curtime
可以使用绝对导入,指定完整的路径就可以解决,但是如果层次比较多就不推荐使用这个:
from 项目名称.tool.timetool import get_curtime
尝试了sys.path.append,测试后还是有问题,不知道是不是哪里写错了:
import sys
sys.path.append("..")
from tool.timetool import get_curtime
目前没有找到更好的解决办法,如果大家有的话可以在评论区告诉我,谢谢!!
真的很需要了!
测试代码:
from autotestprjencrypt.ocr import imgtotxt
from autotestprjencrypt.tool import timetool
curtime=timetool.get_curtime()
print(curtime)
imgtotxt.ocr_img_text(saveimg=True, printResult=True)
也能够正常运行:
ctrl+鼠标左键去看代码,可以看到是完全看不懂源代码的:
加密ok!
使用ok!
参考:Python源码保护 - 知乎