最小的结构¶
让我们来看一小段代码:
def joke():
return (u'How do you tell HTML from HTML5?'
u'Try it out in Internet Explorer.'
u'Does it work?'
u'No?'
u'It\'s HTML5.')
这小段代码仅仅是为了展示如何打包和分发Python代码, 没有实际的用途。
选择一个包名¶
Python 模块或者包名应该遵守以下的规则:
全小写
不要和pypi上已有的包名重复,即使你不想公开发布你的包,因为你的包可能作为其他包的依赖包
使用下划线分隔单词或者什么都不用(不要使用连字符)
现在把我们的函数变成一个Python module funniest
开始工作¶
目录结构 funniest 如下:
funniest/
funniest/
__init__.py
setup.py
最外层的目录是我们版本管理工具的根目录, 例如 funniest.git
. 子目录也叫 funniest
, 代表Python module.
为了更好理解, 我们把函数 joke()
放到 __init__.py
中:
def joke():
return (u'How do you tell HTML from HTML5?'
u'Try it out in Internet Explorer.'
u'Does it work?'
u'No?'
u'It\'s HTML5.')
最主要的setup配置文件是 setup.py
, 应该包含一行代码调用 setuptools.setup()
,就像下面这样:
from setuptools import setup
setup(name='funniest',
version='0.1',
description='The funniest joke in the world',
url='http://github.com/storborg/funniest',
author='Flying Circus',
author_email='flyingcircus@example.com',
license='MIT',
packages=['funniest'],
zip_safe=False)
现在我们可以在本地安装这个python包:
$ python setup.py install
我们也可以使用开发模式安装这个包, 每次修改代码之后不用重新安装, 立即可用最新的代码.:
$ python setup.py develop
不管用哪种方式,安装之后就可以在python中使用这个包:
>>> import funniest
>>> print funniest.joke()
在PyPI上发布¶
脚本 setup.py
也是在PyPI注册和上传源码包的入口.
第一步注册这个包(包括注册包名,上传元数据,创建pypi.python.org的页面):
$ python setup.py register
如果从未在PyPI上发布过东西, 你需要创建一个账号, 命令行向导会一步一步告诉你怎么做.
注册之后你可以在PyPI看到这个包的页面 funniest :
http://pypi.python.org/pypi/funniest/0.1
尽管用户可以根据URL链接找到你的git仓库, 但是为了使用方便我们需要上传一个源码包. 用户不需要clone你的git仓库,而且可以使用安装工具 自动化安装和搜索依赖关系.
第二步创建一个源码包:
$ python setup.py sdist
这一步会在你的顶层目录下创建 dist/funniest-0.1.tar.gz
. 如果你有时间, 可以把这个文件拷贝到另一台主机上, 解压然后安装,
测试一下安装包.
第三步上传到PyPI:
$ python setup.py sdist upload
你可以把这几步结合起来, 更新元数据, 发布新版本, 一步就完成:
$ python setup.py register sdist upload
想要查看setup.py更多的功能可以看看帮助:
$ python setup.py --help-commands
安装这个包¶
上面的步骤完成之后, 其他用户可以直接用 easy_install
安装:
easy_install funniest
或者使用 pip
$ pip install funniest
如果这包作为其他包的依赖包, 它将被自动安装(我们在后面会提到如何配置)
添加其他文件¶
大部分时间我们的代码分散在多个文件当中,
举个例子, 我们把函数移动到一个新的文件中 text
, 现在我们的目录结构是这样子的:
funniest/
funniest/
__init__.py
text.py
setup.py
__init__.py
from .text import joke
text.py
def joke():
return (u'How do you tell HTML from HTML5?'
u'Try it out in Internet Explorer.'
u'Does it work?'
u'No?'
u'It\'s HTML5.')
所有的代码应该都在 funniest/funniest/
目录下.
忽略的文件 (.gitignore, etc)¶
我们可能需要一个 .gitignore
或者是其他代码管理工具类似的文件, 因为创建包的过程中会产生一下中间文件, 我们并不想提交到代码仓库当中.
下面是一个 .gitignore
的例子:
# Compiled python modules.
*.pyc
# Setuptools distribution folder.
/dist/
# Python egg metadata, regenerated from source files by setuptools.
/*.egg-info
大功告成¶
上面讲的结构已经包含了创建一个包的所有步骤. 如果所有的Python工具和库都遵循同样的规则来打包, 世界会更加美好.
客官别急 下面还有更多内容, 因为大部分的包还需要命令行脚本, 文档, 测试,分析工具等等, 请看下一篇.