• 批量编译生成python的pyd文件


    我们编写的程序源代码,或者下一个小的脚本文件需要对外发布时,我们有时候不想让别人能轻易地看到我们的源码,可以将其编译成pyd形式地进行外发,pyd相对于pyc和pyo编译文件,他们两种文件形式差不多,也很容易被反编译,pyd格式是D语言(C/C++综合进化版本)生成的二进制文件,实际也是DLL文件,这种格式文件目前好像是没有可以反编译的消息,只能反汇编。这种文件区别于打包成exe是它生成的pyd文件还可以是原来项目的目录结构,对于项目开发者来说释放出去之后出现问题也方便定位。废话多说,上代码比较。

    以获取当前工作目录的代码为例,我们对比一下pyc文件和pyd文件的区别

    源码 假定文件是current_path.py

    1 import time
    2 import os
    3 4 while 1:
    5   time.sleep(1)
    6   print(os.getcwd())

    在该文件的目录下打开python解释器执行

     可以看到在当前目录下生成一个__pychache__的文件夹,打开会有一个同名的pyc文件

     打开之后,

     还是多少能看到点源码的,这个就违背了不想让人看到源码的初衷了,我们再来看下生成的pyd文件,

    这就很nice了。下面介绍具体方法:

    1、安装Cython,python下很简单,pip3 install cython 即可

    2、准备源文件、即上面的current_path.py

    3、准备打包文件 set_up.py 内容如下

    from distutils.core import setup
    from Cython.Build import cythonize
    ​
    setup(ext_modules=cythonize("set_up.py"))

    4、在当前目录下执行

    python set_up.py build_ext --inplace

    5、报错  Unable to find vcvarsall.bat

    解决办法 安装Visual studio 官网下载社区版即可安装时选择Python开发进行安装(下图是找的,自己安装的时候忘记截图了,懒得截了)

     

    python setup.py build_ext --inplace

    在超过二级目录的时候会额外多一级目录,目前还没有好的办法解决,希望看到这例的读者能提供一个好的建议。再有就是如果项目中出现了同名的set_up.py时,要记得单独编译一下。

     

    将其重命名,去掉 cp37-win_amd64.,将其移动到源文件位置删除源文件,就可以使用了,但是不是直接执行该文件,而是去另外一个文件例去导入该文件的函数或者类,执行另外一个py文件,这时候就执行成功了。跟正常的源文件一样,这时候就满足了需求。

    上述是单个打包成pyd文件,但是批量打包的话这样做很难受,我看到的只是批量生成pyc文件的命令,但是没有批量生成pyd文件的命令,于是自己就写了一段程序供大家参考,代码如下 create_pyd_file.py

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # @time: 2021/5/26 14:17
    # @File: create_pyd_file.py
    import os
    import shutil
    import time
    import sys
    ​
    ​
    def func(path):
        folder_path = os.path.dirname(path)
        file_path = os.path.split(path)[1]
        os.chdir(folder_path)
        with open('setup.py', 'w') as f:
            f.write('from setuptools import setup
    ')
            f.write('from Cython.Build import cythonize
    ')
            f.write('setup(
    ')
            f.write("name='test',
    ")
            f.write("ext_modules=cythonize('%s')
    " % file_path)
            f.write(")
    ")
        os.system('python setup.py build_ext --inplace')
        filename = file_path.split('.py')[0]
        time.sleep(2)
        # 这里的cp37-win_amd64需要注意一下,这个是依据python解释器类型以及windows版本生成的,建议是单个生成一个pyd文件然后相应修改一下
        os.rename('%s\%s.cp37-win_amd64.pyd' % (folder_path, filename), '%s\%s.pyd' % (folder_path, filename))
        # 这个是删除py源文件,测试的时候可以先注释掉查看效果
        os.remove('%s.c' % filename)
        build_folder_path = os.path.join(folder_path, 'build')
        # 删除掉生成的build文件夹
        shutil.rmtree(build_folder_path)
        os.remove('setup.py')
        os.remove(file_path)
    ​
    ​
    def get_all_file(path):
        for root, dirs, files in os.walk(path):
            for name in files:
                if name.endswith(".py"):
                    file_path = os.path.join(root, name)
                    func(file_path)
    ​
    ​
    paths = sys.argv[1]
    get_all_file(paths)
    ​

    调用的方法是在该文件当前路径下执行 加上项目的绝对路径 比如

    python create_pyd_file.py D:python_demodemo

    测试的时候在windows以及ubuntu上二级目录都可以编译成pyd文件并替换到原来的位置 现在有点问题的就是再深层级的目录就出现问题了,原因是这条命令

    更多精彩,可以关注楼主的公众号,

    最全面的django面试题总结: 回复django面试题即可获取, pycharm供给激活压缩包, 回复pycharm破解包即可获取,破解步骤在我的这一篇博客(点我直达)已经破解百次, 屡试不爽.

    以及其他楼主精心打造的原创文章,欢迎各位来访.

  • 相关阅读:
    bzoj1081 [SCOI2005]超级格雷码
    bzoj3790 神奇项链
    bzoj2822 [AHOI2012]树屋阶梯
    bzoj1485 [HNOI2009]有趣的数列
    bzoj1486 [HNOI2009]最小圈
    bzoj2721 [Violet 5]樱花
    POJ 1238 Substrings
    ZOJ Team Formation
    POJ 1459 Power Network
    POJ 1458 Common Subsequence
  • 原文地址:https://www.cnblogs.com/f-g-f/p/14854537.html
Copyright © 2020-2023  润新知