python3打包之setuptools

Python包管理工具setuptools详解

是什么
setuptools是Python distutils增强版的集合,它可以帮助我们更简单的创建和分发Python包

1.创建一个简单的包

cd /tmp 
mkdir demo
cd demo

在demo中创建一个setup.py文件,写入

from setuptools import setup, find_packages
setup(
    name = "demo", #包名,真正调用的不是这个包名,这只是一个宏观的包名
    version = "0.1", #版本号
    packages = find_packages(), #所有包含的其他包
)

执行 python setup.py bdist_egg 即可打包一个包

demo
|-- build
|   `-- bdist.linux-x86_64
|-- demo.egg-info
|   |-- dependency_links.txt
|   |-- PKG-INFO
|   |-- SOURCES.txt
|   `-- top_level.txt
|-- dist
|   `-- demo-0.1-py2.7.egg
`-- setup.py

在dist中生成的是egg包

file dist/demo-0.1-py2.7.egg
dist/demo-0.1-py2.7.egg: Zip archive data, at least v2.0 to extract

看一下生成的.egg文件,是个zip包,解开看看先

upzip -l dist/demo-0.1-py2.7.egg

Archive:  dist/demo-0.1-py2.7.egg
  Length      Date    Time    Name
---------  ---------- -----   ----
        1  2013-06-07 22:03   EGG-INFO/dependency_links.txt
        1  2013-06-07 22:03   EGG-INFO/zip-safe
      120  2013-06-07 22:03   EGG-INFO/SOURCES.txt
        1  2013-06-07 22:03   EGG-INFO/top_level.txt
      176  2013-06-07 22:03   EGG-INFO/PKG-INFO
---------                     -------
      299                     5 files

2.给包增加内容
上面生成的egg中没有实质的内容,显然谁也用不了,现在我们稍微调色一下,增加一点内容。
在demo中执行mkdir demo,再创建一个目录,在这个demo目录中创建一个init.py的文件,表示这个目录是一个包,然后写入:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

def test():
    print "hello world!"  

if __name__ == '__main__':
    test()
    

现在的主目录结构为下:

demo
|-- demo
|   `-- __init__.py
`-- setup.py
再次执行python setup.py bdist_egg后,再看egg包

Archive:  dist/demo-0.1-py2.7.egg
  Length      Date    Time    Name
---------  ---------- -----   ----
        1  2013-06-07 22:23   EGG-INFO/dependency_links.txt
        1  2013-06-07 22:23   EGG-INFO/zip-safe
      137  2013-06-07 22:23   EGG-INFO/SOURCES.txt
        5  2013-06-07 22:23   EGG-INFO/top_level.txt
      176  2013-06-07 22:23   EGG-INFO/PKG-INFO
       95  2013-06-07 22:21   demo/__init__.py
      338  2013-06-07 22:23   demo/__init__.pyc
---------                     -------
      753                     7 files
 

这回包内多了demo目录,已经有了我们自己的东西了,安装体验一下。

python setup.py install

这个命令会将我们创建的egg安装到python的dist-packages目录下,我这里的位置在

tree /usr/local/lib/python2.7/dist-packages/demo-0.1-py2.7.egg

查看一下它的结构:

/usr/local/lib/python2.7/dist-packages/demo-0.1-py2.7.egg
|-- demo
|   |-- __init__.py
|   `-- __init__.pyc
`-- EGG-INFO
    |-- dependency_links.txt
    |-- PKG-INFO
    |-- SOURCES.txt
    |-- top_level.txt
    `-- zip-safe

打开python终端或者ipython都行,直接导入我们的包

>>> import demo
>>> demo.test()
hello world!
>>>

好了,执行成功!

3.setuptools进阶
使用find_packages()
对于简单工程来说,手动增加packages参数很容易,刚刚我们用到了这个函数,它默认在和setup.py同一目录下搜索各个含有init.py的包。其实我们可以将包统一放在一个src目录中,另外,这个包内可能还有aaa.txt文件和data数据文件夹。

demo
├── setup.py
└── src
    └── demo
        ├── __init__.py
        ├── aaa.txt
        └── data
            ├── abc.dat
            └── abcd.dat 

如果不加控制,则setuptools只会将init.py加入到egg中,想要将这些文件都添加,需要修改setup.py

from setuptools import setup, find_packages
setup(
    packages = find_packages('src'),  # 包含所有src中的包
    package_dir = {'':'src'},   # 告诉distutils包都在src下

    package_data = {
        # 任何包中含有.txt文件,都包含它
        '': ['*.txt'],
        # 包含demo包data文件夹中的 *.dat文件
        'demo': ['data/*.dat'],
    }
)

这样,在生成的egg中就包含了所需文件了。看看:

Archive:  dist/demo-0.0.1-py2.7.egg
  Length     Date   Time    Name
 --------    ----   ----    ----
       88  06-07-13 23:40   demo/__init__.py
      347  06-07-13 23:52   demo/__init__.pyc
        0  06-07-13 23:45   demo/aaa.txt
        0  06-07-13 23:46   demo/data/abc.dat
        0  06-07-13 23:46   demo/data/abcd.dat
        1  06-07-13 23:52   EGG-INFO/dependency_links.txt
      178  06-07-13 23:52   EGG-INFO/PKG-INFO
      157  06-07-13 23:52   EGG-INFO/SOURCES.txt
        5  06-07-13 23:52   EGG-INFO/top_level.txt
        1  06-07-13 23:52   EGG-INFO/zip-safe
 --------                   -------
      777                   10 files

也可以通过exclude来排除它

find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"])

1)包含所有包内文件

from setuptools import setup, find_packages
setup(
    ...
    include_package_data = True
)

2)包含一部分,排除一部分

from setuptools import setup, find_packages
setup(
    ...
    packages = find_packages('src'),  
    package_dir = {'':'src'},   

    include_package_data = True,    

    # 排除所有 README.txt
    exclude_package_data = { '': ['README.txt'] },
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值