使用Cython编译一把项目

       Python是解释型语言,没有办法直接编译。个人认为python run time性能较弱在绝大多数场景下是个伪命题,性能弱鸡基本都是代码写的问题,跟人家python没啥关系。之所以会想着编译下,是为了保护源码。毕竟pyc这种东西一键反编译,自欺欺人不太好。OK, 下面直接贴代码~

from distutils.core import setup
from Cython.Build import cythonize
from shutil import copyfile, rmtree
import os

store_path = '你想要把项目编译后放的路径'
store_dir = '可以给编译后的项目一个新名字~'


for root, dirs, files in os.walk(".", topdown=True):
    base_dir = os.path.join(store_dir, root.replace('.', store_dir))
    if not os.path.exists(base_dir):
        os.mkdir(base_dir)
    for dir in dirs:
        if not os.path.exists(os.path.join(base_dir, dir)):
            os.mkdir(os.path.join(base_dir, dir))
    # 上面的代码是按照项目的目录再创建一个空的目录
    for file in files:
        # 只编译 .py 文件
        if file[-3:] == '.py':
            setup(ext_modules=cythonize([os.path.join(root, file)], compiler_directives={'language_level': 3}),
                  script_args=["build_ext"])
            # 轮询编译后的临时文件目录,抓取.so文件
            for ro, d, fi in os.walk('./build'):
                for f_name in fi:
                    if f_name[-3:] == '.so':
                        # 把.so文件复制到它应该在的位置
                        copyfile(os.path.join(ro, f_name), os.path.join(base_dir, f_name))
                    # 删除临时文件
                    os.remove(os.path.join(ro, f_name))
        else:
            # 把非py文件直接放到对应的位置
            copyfile(os.path.join(root, file), os.path.join(base_dir, file))


# 轮询删掉所有临时生成的.c文件
for root, dirs, files in os.walk(".", topdown=True):
    for file in files:
        if file[-2:] == '.c':
            os.remove(os.path.join(root, file))

# 删除build临时目录
rmtree('./build')

用法: 把这个文件丢进项目的根目录下,直接执行.

 

接下来说坑:

1. 文件名格式一定要标准, 什么中划线啊,特殊符号什么的,统统会报错。

2. 代码里的错误,就是红线一类,清理干净,不然也编译不成功。

3. 代码里的传参方式,入口文件直接引用的文件内,传参不允许出现(k=v)形式的传递,多个参数需要按位置传递,尽量向C靠近。

PS: 当确定要编译的化不妨提前注意代码的传参方式,避免kv传参。

4.  假如使用了Python注解,编译后的代码运行将变成强类型...举个栗子:

def func(name: str, op: str, val: str, belongs: dict, default: str) -> str:
    ...

     就是这种写法,在纯python环境下,这个注解就是个注释...我们注解为str,想传啥就传啥...python不管的!但是,一旦我们用Cython编译后,它就不是python了,而是强类型的C。所以,严格意义上讲,这并不算是坑,因为python之所以慢,主要原因是它是弱类型,写的时候轻松,运行的时候解释器需要消耗资源和时间去解决类型的问题。

 

      综上,Cython编译除了可以解决源码安全问题,不失为一种提升python性能的手段,前提是需要注意代码的一些写法。但还是不推荐使用。毕竟和pypi一样,也许性能确实可以提升,但是可靠性至今也没有得到验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值