Python深入:setuptools简介

         Setuptools是Python Distutils的加强版,使开发者构建和发布Python包更加容易,特别是当包依赖于其他包时。用setuptools构建和发布的包与用Distutils发布的包是类似的。包的使用者无需安装setuptools就可以使用该包。如果用户是从源码包开始构建,并且没有安装过setuptools的话,则只要在你的setup脚本中包含一个bootstrap模块(ez_setup),用户构建时就会自动下载并安装setuptools了。

 

一:基本用例

         下面是一个使用setuptools的简单例子:

from setuptools import setup, find_packages
setup(
    name = "HelloWorld",
    version = "0.1",
    packages = find_packages(),
)

         上面就是一个最简单的setup脚本,使用该脚本,就可以产生eggs,上传PyPI,自动包含setup.py所在目录中的所有包等。

         当然,上面的脚本过于简单,下面是一个稍微复杂的例子:

from setuptools import setup, find_packages
setup(
    name = "HelloWorld",
    version = "0.1",
    packages = find_packages(),
    scripts = ['say_hello.py'],

    # Project uses reStructuredText, so ensure that the docutils get
    # installed or upgraded on the target machine
    install_requires = ['docutils>=0.3'],

    package_data = {
        # If any package contains *.txt or *.rst files, include them:
        '': ['*.txt', '*.rst'],
        # And include any *.msg files found in the 'hello' package, too:
        'hello': ['*.msg'],
    },

    # metadata for upload to PyPI
    author = "Me",
    author_email = "me@example.com",
    description = "This is an Example Package",
    license = "PSF",
    keywords = "hello world example examples",
    url = "http://example.com/HelloWorld/",   # project home page, if any
    # could also include long_description, download_url, classifiers, etc.
)

         上面的脚本包含了更多的信息,比如依赖、数据文件、脚本等等,接下来的几节会详细解释。

 

二:find_packages

         对于简单的工程,使用setup函数的packages参数一一列出安装的包到就足够了。但是对于大型工程来说,这却有点麻烦,因此就有了setuptools.find_package()函数。

         find_packages的参数有:一个源码目录,一个include包名列表,一个exclude包名列表。如果这些参数被忽略,则源码目录默认是setup.py脚本所在目录。该函数返回一个列表,可以赋值给packages参数。

         有些工程可能会使用src或者lib目录作为源码树的子目录,因此这些工程中,需要使用”src”或者”lib”作为find_packages()的第一个参数,当然,这种情况下还需要设置package_dir = {'':'lib'},否则的话会报错,比如setup脚本如下:

from setuptools import setup, find_packages
setup(
    name = "HelloWorld",
    version = "0.1",
    package_dir = {'':'lib'},
    packages = find_packages('lib'),
)

        源码树如下:

lib/
    foo.py
    heheinit.py
    bar/
        __init__.py
        bar.py

         最终生成的文件是:

/usr/local/lib/python2.7/dist-packages/HelloWorld-0.1-py2.7.egg-info/dependency_links.txt

/usr/local/lib/python2.7/dist-packages/HelloWorld-0.1-py2.7.egg-info/PKG-INFO

/usr/local/lib/python2.7/dist-packages/HelloWorld-0.1-py2.7.egg-info/SOURCES.txt

/usr/local/lib/python2.7/dist-packages/HelloWorld-0.1-py2.7.egg-info/top_level.txt

/usr/local/lib/python2.7/dist-packages/bar/bar.py

/usr/local/lib/python2.7/dist-packages/bar/bar.pyc

/usr/local/lib/python2.7/dist-packages/bar/__init__.py

/usr/local/lib/python2.7/dist-packages/bar/__init__.pyc

 

         如果没有package_dir = {'':'lib'}的话,则会报错:

error: package directory 'bar' does not exist

              这是因为执行函数find_packages('lib'),返回的结果是['bar'],没有package_dir = {'':'lib'}的话,则在setup.py所在目录寻找包bar,自然是找不到的了。

>>> import setuptools
>>> setuptools.find_packages('lib')
['bar']

         find_packages()函数遍历目标目录,根据include参数进行过滤,寻找Python包。对于Python3.2以及之前的版本,只有包含__init__.py文件的目录才会被当做包。最后,对得到的结果进行过滤,去掉匹配exclude参数的包。

         include和exclude参数是包名的列表,包名中的’.’表示父子关系。比如,如果源码树如下:

lib/
    foo.py
    __init__.py
    bar/
        __init__.py
        bar.py

        则find_packages(exclude=["lib"])(或packages = find_packages(include=["lib"])),只是排除(或包含)lib包,但是却不会排除(或包含lib.bar)包。

 

三:entry points

         entry points是发布模块“宣传”Python对象(比如函数、类)的一种方法,这些Python对象可以被其他发布模块使用。一些可扩展的应用和框架可以通过特定的名字找到entry points,也可以通过发布模块的名字来找到,找到之后即可加载使用这些对象了。


         entry points要属于某个entry points组,组其实就是一个命名空间。在同一个entry point组内不能有相同的entry point。

         

         entry points通过setup函数的entry_points参数来表示,这样安装发布包之后,发布包的元数据中就会包含entry points的信息。entry points可以实现动态发现和执行插件&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值