1、前言

封装打包Python的好处,节省了安装各种各样包依赖的问题,同时可以加强我们代码隐私的安全性,这里我的演示环境是Python3.6 ,CentOS7的系统,同时打包工具采用pyinstaller。

2、环境准备

2.1 Python共享so模块

默认Python模块是私有的,我们想打包就需要将我们的so模块变为共享的,那么我们需要执行两个操作即可。

  1. 重新编译Python,加入编译参数 --enable-shared
  2. 将so共享库加入到系统之中
  1. [root@c7-work-1 ~]# cat /etc/ld.so.conf.d/python3.6.conf
  2. /usr/local/python3.6.5-shared/lib
  3. [root@c7-work-1 ~]# ldconfig

完成上面操作即可了。

2.2 安装pyinstaller

  1. pip install pyinstaller

2.3 准备工程

这里我们只需要准备工程和相关依赖包,并且安装成功即可,程序能正常跑则没问题。

这里根据自己经验来即可了,没啥技巧。

3、代码调整

默认情况下,我们打包后有些代码原有的获取方式会有些转变。

3.1 运行时的环境

当应用程序运行时,可能需要访问以下三个常规位置中的任何位置的数据文件:

  • 捆绑在一起的数据文件;
  • 用户的配置文件;
  • 用户工作目录中的文件

在Python中我们需要注意提防如下:

P1: 使用__file__sys._MEIPASS

当程序未冻结时,标准Python变量__file__是现在正在执行的脚本的完整路径。当捆绑的应用程序启动时,引导加载程序会设置sys.frozen属性并将绝对路径存储到bundle文件夹中sys._MEIPASS。对于单文件夹捆绑包,这是该文件夹的路径,无论用户在哪里放置它。对于单文件包,这是 引导加载程序创建的临时文件夹的路径(请参阅单文件程序的工作原理)。_MEIxxxxxx

P2: 使用sys.executablesys.argv[0]

当正常的Python脚本运行时,sys.executable是执行程序的路径,即Python解释器。在一个冻结的应用sys.executable程序中,也是执行程序的路径,但这不是Python; 它是单文件应用程序中的引导加载程序或单文件夹应用程序中的可执行文件。这为您提供了一种可靠的方法来查找用户实际启动的冻结可执行文件。

sys.argv[0]是用户命令中使用的名称或相对路径。它可能是相对路径或绝对路径,具体取决于平台以及应用程序的启动方式。

下面是一个演示代码,有兴趣可以执行下看看效果:

  1. #!/usr/bin/python3
  2. import sys, os
  3. frozen = 'not'
  4. if getattr(sys, 'frozen', False):
  5. # we are running in a bundle
  6. frozen = 'ever so'
  7. bundle_dir = sys._MEIPASS
  8. else:
  9. # we are running in a normal Python environment
  10. bundle_dir = os.path.dirname(os.path.abspath(__file__))
  11. print( 'we are',frozen,'frozen')
  12. print( 'bundle dir is', bundle_dir )
  13. print( 'sys.argv[0] is', sys.argv[0] )
  14. print( 'sys.executable is', sys.executable )
  15. print( 'os.getcwd is', os.getcwd() )

3.2 调整项目代码

根据上面的规则,着重调整一下代码。

原代码:

  1. BASE_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

New代码:

  1. if getattr(sys, 'frozen', False):
  2. BASE_PATH = sys._MEIPASS
  3. else:
  4. BASE_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

只需要启动入口脚本调整即可,其他脚本无需调整

4、打包封装

打包:

  1. pyinstaller thunder_predict.spec

如何生成 *.spec文件呢,可以这里直接pyinstaller pyscript即可,然后在修改调整;下面提供我的实例文件:

  1. # -*- mode: python -*-
  2. block_cipher = None
  3. a = Analysis(['predict/thunder_predict.py'],
  4. pathex=['.'],
  5. binaries=[],
  6. datas=[('model', 'model'), ('dataset', 'dataset')],
  7. hiddenimports=['cython','sklearn','sklearn.ensemble','sklearn.neighbors.typedefs',
  8. 'sklearn.neighbors.quad_tree','sklearn.tree._utils','scipy._lib.messagestream'],
  9. hookspath=[],
  10. runtime_hooks=[],
  11. excludes=[],
  12. win_no_prefer_redirects=False,
  13. win_private_assemblies=False,
  14. cipher=block_cipher,
  15. noarchive=False)
  16. pyz = PYZ(a.pure, a.zipped_data,
  17. cipher=block_cipher)
  18. exe = EXE(pyz,
  19. a.scripts,
  20. [],
  21. exclude_binaries=True,
  22. name='thunder_predict',
  23. debug=False,
  24. bootloader_ignore_signals=False,
  25. strip=False,
  26. upx=True,
  27. console=True )
  28. coll = COLLECT(exe,
  29. a.binaries,
  30. a.zipfiles,
  31. a.datas,
  32. strip=False,
  33. upx=True,
  34. name='thunder_predict')

5、打包So文件库

我们为什么要打包成为so文件呢?

Python有py、pyc、pyw、pyo、pyd等文件格式。

其中,pyc是二进制文件。但很容易被反编译。

pyw也不行,只是隐藏命令行界面而已,可以作为入口脚本。

pyo和pyc差不多,也容易被反编译。

最后剩下pyd格式。pyd格式是D语言(C/C++综合进化版本)生成的二进制文件,实际也会是dll文件。该文件目前位置没找到可以被反编译的消息,只能被反汇编。Sublime text编辑器也是使用该格式。

5.1 打包So模块

打包生成so文件:

  1. python3 ../utils/build_so.py build_ext --inplace

清理无用的文件:

  1. rm -fr build main.c main.py

测试(成功测试成功):

  1. [root@c7-work-1 thunder]# python3 predict/thunder_predict.py 01:dXBsb2FkRGF0YTE1MzI2Nzk4MzQzNDI= 199
  2. success

Cython脚本内容:

  1. from distutils.core import setup
  2. from Cython.Build import cythonize
  3. """
  4. python build_so.py build_ext --inplace
  5. """
  6. setup(
  7. name = 'main',
  8. ext_modules = cythonize("main.py"),
  9. )

5.2 重新打包整个

命令如下:

  1. [root@c7-work-1 thunder]# pyinstaller thunder_predict.spec
  2. 36 INFO: PyInstaller: 3.4
  3. 37 INFO: Python: 3.6.5
  4. ................ 省略一下信息

我们检查一下是否已经将我们的So库文件打包。

  1. [root@c7-work-1 thunder]# ls dist/thunder_predict/main.cpython-36m-x86_64-linux-gnu.so
  2. dist/thunder_predict/main.cpython-36m-x86_64-linux-gnu.so

完美。

5.3 完美之余有些略显通俗的坑

Q: pyinstaller利用获取脚本中import来来打包对应的库,如果你打包成so文件了还可以?

A: 这里我通过Python PKG的方式,将so会差别的库放入到__init__.py中,就可以解决这个问题。

封装打包Python脚本的更多相关文章

  1. 打包python脚本为exe可执行文件-pyinstaller和cx_freeze示例

    本文介绍使用cx_freeze和pyinstaller打包python脚本为exe文件 cx_freeze的使用实例 需要使用到的文件wxapp.py, read_file.py, setup.py ...

  2. PyInstaller打包python脚本的一些心得

    PyInstaller打包python脚本的一些心得 因为在公司经常要帮同事做一个从excel表格中提取出需要的内容的重复工作,比较繁琐还容易出错:于是就想着要写个程序,但是同事又不可能在电脑上也装上 ...

  3. 打包python脚本为exe的坎坷经历, by pyinstaller方法

    打包python脚本为exe的坎坷经历, by pyinstaller方法 又应验了那句歌词. 不经历风雨, 怎么见得了彩虹. 安装过程略去不提, 仅提示: pip install pyinstall ...

  4. PyInstaller打包Python脚本为exe

    1.PyInstaller-3.1.1  百度云链接  http://pan.baidu.com/s/1jHYWin8 密码  oapl 2.安装最新版本的 pywin32-217.win32-py2 ...

  5. 用Py2exe打包Python脚本简单介绍

    一.简述      Py2exe,从这个名字上就可以理解,把Python脚本转换为windows平台上面可以运行的可执行程序(*.exe)的工具.经过转换后,你可以不 用安装Python的执行环境就可 ...

  6. py2exe打包python脚本

    在工作中遇到将python脚本转换成exe可执行程序的需求,通过查询可以使用py2exe来构建满足要求的程序,这里简要说明一下使用步骤. 一.py2exe是一个将python脚本转换成windows上 ...

  7. 40、IOS自动打包-Python脚本

    第一种:基于编译的打包 编译工程--找到.app文件--新建Payload文件夹--拷贝.app到Payload文件夹--压缩成zip--更改后缀名为ipa--完成! 第二种(有问题,暂时不需要看) ...

  8. PyInstaller打包python脚本

    用python写的工具写好了,想打包然后发给测试同事使用,最后选择了PyInstaller,支持Windows.Linux.OS X,支持打包成一个文件夹或单个EXE文件.   我是直接在线安装的,在 ...

  9. 打包python脚本为exe

    更新pip 安装

随机推荐

  1. 浅谈java中的枚举类型(转)

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  2. git基础-远程仓库的使用

    远程仓库的使用 为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库. 远程仓库是指托管在因特网或其他网络中的你的项目的版本库. 你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以 ...

  3. Linux系统性能排查

    一.性能监控Sar命令 语法格式: [root@cdh init.d]# sar -h -A:所有报告的总和 -b:显示I/O和传递速率的统计信息 -B:显示换页状态 -d:输出每一块磁盘的使用信息 ...

  4. spark进行相同列的join时,只留下A与B关系,不要B与A

    一.问题需求: 近期需要做一个商品集合的相关性计算,需要将所有商品进行两两组合笛卡尔积,但spark自带的笛卡尔积会造成过多重复,而且增加join量 假如商品集合里面有: aa   aa bb   b ...

  5. Kali Debian 修改时区

    1.KaliDebian默认读取时区文件是/etc/localtime(重建软连接,达到修改时区目的) 2./etc/localtime是个软连接,连接到时区文件/usr/share/zoneinfo ...

  6. 机器学习算法-PCA降维技术

    机器学习算法-PCA降维 一.引言 在实际的数据分析问题中我们遇到的问题通常有较高维数的特征,在进行实际的数据分析的时候,我们并不会将所有的特征都用于算法的训练,而是挑选出我们认为可能对目标有影响的特 ...

  7. (四)React Ant Design Pro + .Net5 WebApi:PostgreSQL数据库环境搭建

    一.简介 PostgreSQL,开源数据库(没听过小伙伴自己反思一下自行百度) PgAdmin,官方提供的数据库管理工具. 二.环境 1. 官网下载包,安装数据库 tar xjvf /app/pack ...

  8. 理解C#中的 async await

    前言 一个老掉牙的话题,园子里的相关优秀文章已经有很多了,我写这篇文章完全是想以自己的思维方式来谈一谈自己的理解.(PS:文中涉及到了大量反编译源码,需要静下心来细细品味) 从简单开始 为了更容易理解 ...

  9. powershell中的cmdlet命令

    Add-Computer 向域或工作组中添加计算机. Add-Content 向指定的项中添加内容,如向文件中添加字词. Add-History 向会话历史记录追加条目. Add-Member 向 W ...

  10. Lakehouse: 统一数据仓库和高级分析的新一代开放平台

    1. 摘要 数仓架构在未来一段时间内会逐渐消亡,会被一种新的Lakehouse架构取代,该架构主要有如下特性 基于开放的数据格式,如Parquet: 机器学习和数据科学将被作为头等公民支持: 提供卓越 ...