from:http://liluo.org/blog/2012/08/how-to-create-python-egg/

制作打包一个 Python Egg 并部署整个过程还蛮有意思的,下面小教程(这里以制作一个叫作 bee 的 Egg 为例)~

制作

先创建一个项目文件夹:

1
2
$ mkdir bee-egg # 这个名字可以随便取
$ cd bee-egg

在里边建一个叫 bee 的文件夹(逻辑比较简单的话可以直接建一个叫作 bee.py 的文件),放业务逻辑代码:

1
2
mkdir bee
touch bee/__init__.py

其中 bee/init.py 写几行代码:

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-

def hoot():
return 'hum hum' def add(x, y):
return x + y

在 bee-egg 目录中创建 Egg 的配置文件 setup.py :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python

from setuptools import setup, find_packages

setup(
name = 'bee',
version = '0.0.1',
keywords = ('bee', 'egg'),
description = 'a simple egg',
license = 'MIT License', url = 'http://liluo.org',
author = 'liluo',
author_email = 'i@liluo.org', packages = find_packages(),
include_package_data = True,
platforms = 'any',
install_requires = [],
)

*setup 中完整的参数及说明可以看 http://docs.python.org/distutils/setupscript.html#additional-meta-data

当前目录文件结构如下:

1
2
3
4
bee-egg/
bee/
__init__.py
setup.py

打包

打包是最重要却又最简单的一步,执行:

1
python setup.py xxxx

即可。比较主流的2种打包格式:

1
2
3
# 以下所有生成文件将在当前路径下 dist 目录中
python setup.py bdist_egg # 生成类似 bee-0.0.1-py2.7.egg,支持 easy_install
python setup.py sdist # 生成类似 bee-0.0.1.tar.gz,支持 pip

当然还有其他非主流格式或者其他选项,可以通过下面这个命令查看:

1
python setup.py --help-commands

部署到 PyPI

注册 Egg

可以通过 SSH 或者 web form ,SSH 步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ python setup.py register
running register
running egg_info
writing bee.egg-info/PKG-INFO
writing top-level names to bee.egg-info/top_level.txt
writing dependency_links to bee.egg-info/dependency_links.txt
reading manifest file 'bee.egg-info/SOURCES.txt'
writing manifest file 'bee.egg-info/SOURCES.txt'
running check
We need to know who you are, so please choose either:
1. use your existing login,
2. register as a new user,
3. have the server generate a new password for you (and email it to you), or
4. quit
Your selection [default 1]: Username: liluo
Password:
Registering bee to http://pypi.python.org/pypi
Server response (200): OK
I can store your PyPI login so future submissions will be faster.
(the login will be stored in /Users/luo/.pypirc)
Save your login (y/N)?y

*关于 register 更详细的内容可以看 http://docs.python.org/distutils/packageindex.html

上传到 PyPI

上传文件也是有 SSH 和 web form 2种方法。

web form: 在浏览器登陆到 PyPI 点击 Your packages 中 Egg 的项目,然后选择某个版本的 files 即可看到上传界面。

SSH:

1
2
3
4
5
6
7
8
$ python setup.py sdist bdist_egg upload
# 这里上传的是 .tar.gz 压缩包和 .egg 文件
# 屏幕上大片信息输出,最后会看到
running upload
Submitting dist/bee-0.0.1.tar.gz to http://pypi.python.org/pypi
Server response (200): OK
Submitting dist/bee-0.0.1-py2.7.egg to http://pypi.python.org/pypi
Server response (200): OK

安装测试

先用 pip 安装:

1
2
3
4
5
6
7
8
9
10
$ pip install bee
Downloading/unpacking bee
Downloading bee-0.0.1.tar.gz
Running setup.py egg_info for package bee Installing collected packages: bee
Running setup.py install for bee Successfully installed bee
Cleaning up...

测试:

1
2
3
4
5
6
7
8
9
$ python
>>> import bee
>>> dir(bee)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'add', 'hoot']
>>> bee.add(1,3)
4
>>> from bee import hoot
>>> hoot()
'hum hum'

Yeah!现在世界人民都可以用 [bee]http://pypi.python.org/pypi/bee/ 这个 Python Egg 了~

卸载掉用 easy_install 试下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ pip uninstall bee
Uninstalling bee:
/Library/Python/2.7/site-packages/bee
/Library/Python/2.7/site-packages/bee-0.0.1-py2.7.egg-info
Proceed (y/n)? y
Successfully uninstalled bee
$ easy_install bee
Searching for bee
Reading http://pypi.python.org/simple/bee/
Reading http://liluo.org
Best match: bee 0.0.1
Downloading http://pypi.python.org/packages/2.7/b/bee/bee-0.0.1-py2.7.egg#md5=6b5a719f1ca42367fb05d1e3eb45fbe5
Processing bee-0.0.1-py2.7.egg
Moving bee-0.0.1-py2.7.egg to /Library/Python/2.7/site-packages
Adding bee 0.0.1 to easy-install.pth file Installed /Library/Python/2.7/site-packages/bee-0.0.1-py2.7.egg
Processing dependencies for bee
Finished processing dependencies for bee

可以再重做一下上面的测试,验证一下。

*关于 upload 更详细的内容可以看 http://docs.python.org/distutils/uploading.html

Tips

pip install xxxx 时默认只会找对应的压缩包文件

当时我用 easy_install 安装没问题,但是 pip 每次都说找不到资源。我盯着 @hongqn 在 PyPI 上的 CaoE 足足2分钟才反应过来,原来它是需要一个压缩包格式的文件。

setup.py 中调用当前目录的文件一定要加 MANIFEST.in 并将调用文件 include 进来

使用 python setup.py sdist 打包时,如果 setup.py 调用了当前目录中的文件(如README.rst):

1
long_description = open('README.rst').read()

一定要在增加 MANIFEST.in 文件并将调用文件 include 进来,否则将导致用户在 pip install 时报文件找不到的错误,示例:

1
2
$ cat MANIFEST.in
include README.rst

更详情的可以看 http://docs.python.org/distutils/sourcedist.html#specifying-the-files-to-distribute

偶尔去看一下自己的 Egg 在 PyPI 上的下载数也挺欢乐的

1
2
3
4
5
6
7
8
9
10
11
Version: 0.0.3
py-oauth2-0.0.3.tar.gz(251)
py_oauth2-0.0.3-py2.7.egg(218) Version: 0.0.2
py-oauth2-0.0.2.tar.gz(376)
py_oauth2-0.0.2-py2.6.egg(435)
py_oauth2-0.0.2-py2.7.egg(304) Version: 0.0.1
py_oauth2-0.0.1-py2.6.egg(478)

END

Posted by 落 Aug 30th, 2012 Egg, Python

-----------

简单说说如何制作一个自己的egg包。

首先一个问题是“Python的package是如何定义的?”这个似乎是面试Python程序员最常出现的题目。简而言之,在目录下放置一个__init__.py文件,这个目录就会成为一个package。

首先是制作一个干净的目录用于打包,本例中就简单粗暴的定义为~/project目录,要打包的package就命名为spawn-egg(注:这里只是用来Demo的名字,命名方式并不适合所有的python环境)。目录结构如下:

ilab@iLab-Dev:~/project$ find ./
./
./spawn-egg
./spawn-egg/Base.pyc
./spawn-egg/hello.py
./spawn-egg/Base.py
./spawn-egg/__init__.py

然后就是制作一个setup.py脚本,与其说是脚本,这个文件更像是一个配置文件。

vi ~/project/setup.py

from setuptools import setup, find_packages

setup(
name = "spawn-egg",
version="0.1.0",
packages = find_packages(),
description = "test how to make eggs",
author = "Litrin J.",
author_email = "XXX@gmail.com", license = "GPL",
keywords = ("test", "python"),
platforms = "Independant",
url = "",
)

就是一个setup函数,入参真心不少,好在字面上很容易理解它的用途,总结起来就这几个比较常用:

  • name:就是名字了
  • version:版本号
  • packages:包含的package,setuptools自带了一个find_packages()工具可以自动从name同名的folder下找到package。
  • description:对于这个包的描述,如果描述内容很长,可以把这里当成摘要,更详细的内容使用long_description参数
  • author/author_email:作者和邮箱
  • keywords:关键字,便于发布到pip上,用于搜索。

更详细的解释请见

准备打包环境。打包环境需要setuptools,对于Ubuntu用户来说,直接

apt-get install python-setuptools

生成egg,激动人心的时刻来了!

ilab@iLab-Dev:~/project$ python setup.py bdist_egg
running bdist_egg
running egg_info
creating spawn_egg.egg-info
writing spawn_egg.egg-info/PKG-INFO
writing top-level names to spawn_egg.egg-info/top_level.txt
writing dependency_links to spawn_egg.egg-info/dependency_links.txt
writing manifest file 'spawn_egg.egg-info/SOURCES.txt'
reading manifest file 'spawn_egg.egg-info/SOURCES.txt'
writing manifest file 'spawn_egg.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/spawn-egg
copying spawn-egg/hello.py -> build/lib.linux-x86_64-2.7/spawn-egg
copying spawn-egg/Base.py -> build/lib.linux-x86_64-2.7/spawn-egg
copying spawn-egg/__init__.py -> build/lib.linux-x86_64-2.7/spawn-egg
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/spawn-egg
copying build/lib.linux-x86_64-2.7/spawn-egg/hello.py -> build/bdist.linux-x86_64/egg/spawn-egg
copying build/lib.linux-x86_64-2.7/spawn-egg/Base.py -> build/bdist.linux-x86_64/egg/spawn-egg
copying build/lib.linux-x86_64-2.7/spawn-egg/__init__.py -> build/bdist.linux-x86_64/egg/spawn-egg
byte-compiling build/bdist.linux-x86_64/egg/spawn-egg/hello.py to hello.pyc
byte-compiling build/bdist.linux-x86_64/egg/spawn-egg/Base.py to Base.pyc
byte-compiling build/bdist.linux-x86_64/egg/spawn-egg/__init__.py to __init__.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying spawn_egg.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spawn_egg.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spawn_egg.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying spawn_egg.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/spawn_egg-0.1.0-py2.7.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)

OK,egg文件已经在dist文件夹下生成好了,其实就是一个zip文件包,可以简单地用unzip命令check一下!

ilab@iLab-Dev:~/project/dist$ unzip -l spawn_egg-0.1.0-py2.7.egg
Archive: spawn_egg-0.1.0-py2.7.egg
Length Date Time Name
--------- ---------- ----- ----
474 2015-06-10 15:31 spawn-egg/Base.pyc
429 2015-06-10 15:31 spawn-egg/hello.pyc
102 2015-06-10 15:04 spawn-egg/hello.py
137 2015-06-10 15:31 spawn-egg/__init__.pyc
44 2015-06-10 15:04 spawn-egg/Base.py
0 2015-06-10 15:02 spawn-egg/__init__.py
10 2015-06-10 15:31 EGG-INFO/top_level.txt
199 2015-06-10 15:31 EGG-INFO/SOURCES.txt
227 2015-06-10 15:31 EGG-INFO/PKG-INFO
1 2015-06-10 15:31 EGG-INFO/dependency_links.txt
1 2015-06-10 15:31 EGG-INFO/zip-safe
--------- -------
1624 11 files

尝试安装一下

ilab@iLab-Dev:~/project/dist$ sudo easy_install spawn_egg-0.1.0-py2.7.egg
[sudo] password for ilab:
Processing spawn_egg-0.1.0-py2.7.egg
creating /usr/local/lib/python2.7/dist-packages/spawn_egg-0.1.0-py2.7.egg
Extracting spawn_egg-0.1.0-py2.7.egg to /usr/local/lib/python2.7/dist-packages
Adding spawn-egg 0.1.0 to easy-install.pth file Installed /usr/local/lib/python2.7/dist-packages/spawn_egg-0.1.0-py2.7.egg
Processing dependencies for spawn-egg==0.1.0
Finished processing dependencies for spawn-egg==0.1.0

没有报错!这个时候/usr/local/lib/python2.7/dist-packages/就是您安装好的python包,你可以在这里删除/修改您的安装包。

--------

执行python setup.py bdist_egg命令之后,在dist目录下会生成egg文件,egg文件其实只是一个压缩包

制作其他安装文件:

python setup.py build  # 编译
python setup.py sdist  # zip格式包
python setup.py bdist_wininst # exe格式包
python setup.py bdist_rpm # rpm格式包

怎样制作一个 Python Egg的更多相关文章

  1. python egg for centos 制作

    经常接触Python的同学可能会注意到,当需要安装第三方python包时,可能会用到easy_install命令.easy_install是由PEAK(Python Enterprise Applic ...

  2. 用 Python 制作一个艺术签名小工具,给自己设计一个优雅的签名

    生活中有很多场景都需要我们签字(签名),如果是一些不重要的场景,我们的签名好坏基本无所谓了,但如果是一些比较重要的场景,如果我们的签名比较差的话,就有可能给别人留下不太好的印象了,俗话说字如其人嘛,本 ...

  3. 吴裕雄--天生自然python学习笔记:python 用pygame模块制作一个音效播放器

    用 Sound 对象制作一个音效播放器. 应用程序总览 程序在执行后默认会把 WAV 音频文件加载到清单中,单击“播放”按钮可开始 播放,同时显示 “正在播放 xxx 音效”的信息 . 播放过程中,可 ...

  4. TensorFlow练习13: 制作一个简单的聊天机器人

    现在很多卖货公司都使用聊天机器人充当客服人员,许多科技巨头也纷纷推出各自的聊天助手,如苹果Siri.Google Now.Amazon Alexa.微软小冰等等.前不久有一个视频比较了Google N ...

  5. 手把手教你发布一个Python包

    本文主题如下: 编写一个包(Python 源代码),但不是本文的重点. 编译包,观察编译后的文件. 发布包,发布的包可以有多种类型. 如何在 Pypi 中查看已发布的包 注意: 本文编写的包在 Pyt ...

  6. python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐(二)

    在上一篇blog:python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推荐 中介绍了python中的tkinter的一些东西,你可能对tkinter有一定的了解了.这篇b ...

  7. 选择一个 Python Web 框架:Django vs Flask vs Pyramid

    Pyramid, Django, 和 Flask都是优秀的框架,为项目选择其中的哪一个都是伤脑筋的事.我们将会用三种框架实现相同功能的应用来更容易的对比三者.也可以直接跳到框架实战(Framework ...

  8. Helm 从入门到实践 | 从 0 开始制作一个 Helm Charts

    本周 Helm 官方发布博客,指导用户从 v2 迁移到 v3,这标志 Helm 逐渐走向成熟.早在今年 6 月,阿里云就正式发布了国内首个 Helm Hub 中国镜像站:开放云原生应用中心 - Clo ...

  9. 二维码制作分享-Python

    分享一个简单快捷的二维码制作,Python实现. 1.安装准备 已安装的Python+Pycharm的计算机.本人win7+Python3.6+Pycharm 2.库包下载安装 Python二维码制作 ...

随机推荐

  1. sql多列值一行显示

    select stuff(( select ',' + UserNM from tblSysUser for xml path('')), 1,1,'')

  2. Rufus软件

    Rufus软件(https://rufus.akeo.ie/)——制作启动盘必备,简易且开源.

  3. XML解析详解|乐字节

    大家好,乐字节的小乐又来了,Java技术分享哪里少的了小乐!上次我们说了可扩展标记语言XML之二:XML语言格式规范.文档组成,本文将介绍重点——XML解析.   基本的解析方式有两种:一种叫 SAX ...

  4. java8新特性六-Optional 类

    Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容器:它可以保存类型T的值,或者仅仅保 ...

  5. 通过LxRunOffline迁移Win10的Linux子系统

    默认情况WSL装在系统盘(C:),重装系统怎么办?C盘空间不足怎么办?能修改WSL安装路径吗? 当然可以,使用LxRunOffline不仅能修改WSL安装路径,还能备份WSL.还原WSL…… 修改WS ...

  6. PHP设计模式 - 桥接模式

    将抽象部分与它的实现部分分离,使他们都可以独立的变抽象与它的实现分离,即抽象类和它的派生类用来实现自己的对象 桥接与适配器模式的关系(适配器模式上面已讲解): 桥接属于聚合关系,两者关联 但不继承 适 ...

  7. 10 Spring框架--基于注解的IOC配置

    1.工程环境搭建 2.基于注解的IOC配置 IOC注解的分类 (1)用于创建对象的 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的@Component: 作用: ...

  8. vs中web api程序不包含适合于入口点的静态“Main”方法

    步骤:选择该项目的属性--应用程序--输出类型--类库

  9. authenticate的执行流程与重写

    流程 1.authenticate调用的是_get_backends函数 def authenticate(request=None, **credentials): for backend, bac ...

  10. 2019/7/18ACM集训

    2019-07-18 09:15:34 这个是练习刷的题 Vus the Cossack and Numbers Vus the Cossack has nn real numbers aiai. I ...