之前需要给一个项目的python代码打包sdk(即将自己的项目文件和代码打包成egg/whl等包,可以让自己和别人直接import),网上的分享很多,最后弄了很长时间才弄好,现在写个博客记录一下,防止以后忘了麻烦,希望也能给别人提供一点帮助。

关于linux的打包可以参考下面这两个网址:

http://wsfdl.com/python/2015/09/06/Python%E5%BA%94%E7%94%A8%E7%9A%84%E6%89%93%E5%8C%85%E5%92%8C%E5%8F%91%E5%B8%83%E4%B8%8A.html

http://wsfdl.com/python/2015/09/08/Python%E5%BA%94%E7%94%A8%E7%9A%84%E6%89%93%E5%8C%85%E5%92%8C%E5%8F%91%E5%B8%83%E4%B8%8B.html

下面简述一下我在linux下的打包过程:

假设我的项目文件夹结构如下(大写字母代表是文件夹):

DEMO
  |_   __init__.py
  |_   main.py
  |_   DATA
        |_    data1.txt
        |_    data2.xlsx
        |_     __init__.py
        |_    a.py

1、若想打包成sdk,先在和DEMO文件夹同父文件夹下添加4个必要文件:setup.py, setup.cfg(这是一个空文件), README.rst, MANIFEST.in,即:

DEMO_SDK
     |_  DEMO
     |_  setup.py
     |_  setup.cfg
     |_  README.rst
     |_  MANIFEST.in

2、setup.py的内容如下:

import os
import setuptools  # 没有的直接pip install一下就行了   

setuptools.setup(
    name='DEMO',
    version='1.0',
    description='A demo for python packaging.',  # 一个简要的介绍而已
    long_description=open(
        os.path.join(
            os.path.dirname(__file__),
            'README.rst'
        )
    ).read(),
    packages=find_packages(),
    include_package_data = True,   
    author='xxx',
    author_email='xxx@gmail.com',
)

      配合setup.py需要进行以下设置:

      1)README.rst中保存一些说明性语言,可以是包的使用举例code demo;

      2)因为打包过程一般是默认只打包py文件的,因此要想一并打包非py文件,需要在setup.py里加入include_package_data = True这句话和MANIFEST.in文件,关于MANIFEST.in文件的设置如下:

include DEMO/DATA/data1.txt
include DEMO/DATA/data2.xlsx

3、在DEMO_SDK路径下使用:

python setup.py bdist_wheel

将DEMO文件夹等打包为whl包。需要注意的是:这个"python"的版本将直接决定你的whl包的使用环境,即你用的python是2.0版本,你的whl包也是只能用于python2.0版本的,若想保存为通用版本(即2.0,3.0都可以使用),需要使用

python setup.py bdist_wheel --universal

成功打包后的文件夹如下:

DEMO_SDK
    |_  build(打包生成的文件夹)
    |_  dist(打包生成的文件夹)
    |_  DEMO.egg-info(打包生成的文件夹)
    |_  DEMO
    |_  setup.py
    |_  setup.cfg
    |_  MANIFEST.in
    |_  README.rst

  此时将dist文件夹中的whl包发给调用方就好了。

4、调用方拿到whl包以后直接用如下命令即可安装:

pip install DEMO-1.0-py2-none-any.whl

使用即:

from DEMO import main

P.S.若想在main.py文件中调用DATA文件夹中的py包,则需要在main.py文件中添加将当前路径暂时加入环境变量的语句:

import sys, os
sys.path.append(os.path.abspath(os.path.dirname(os.path.realpath(__file__))))  # 获取当前文件父文件夹的绝对路径并暂时添加到环境变量中

      若想在main.py中调用包中的任何数据文件,均需要使用数据文件的绝对路径。

 

至此就完成了打包任务,有几点需要注意的问题罗列如下:

  1. 项目中__init__.py必须存在,虽然内容为空;
  2. MANIFEST.in 内的include数据文件路径应为以MANIFEST.in 路径为当前路径的相对路径;
  3. 最后pip install whl包时,安装的位置为当前python对应的环境。