1、背景

查看flower的源码,首先看到flower的主程序如下:

  1. #!/usr/local/sinasrv2/bin/python2.7
  2. # EASY-INSTALL-ENTRY-SCRIPT: 'flower==0.7.3','console_scripts','flower'
  3. __requires__ = 'flower==0.7.3'
  4. import sys
  5. from pkg_resources import load_entry_point
  6.  
  7. if __name__ == '__main__':
  8. sys.exit(
  9. load_entry_point('flower==0.7.3', 'console_scripts', 'flower')()

load_entry_point,它的信息来源是entry_points.txt

entry_points.txt来源呢?

setup.py里面有entry_points 信息,会根据这些信息生成egg info目录,里面有entry_points.txt文件, 里面的内容就是setup.py里的entry_points信息

  1. setup(
  2. name='flower',
  3. version=get_package_version(),
  4. description='Celery Flower',
  5. long_description=open('README.rst').read(),
  6. author='Mher Movsisyan',
  7. author_email='mher.movsisyan@gmail.com',
  8. url='https://github.com/mher/flower',
  9. license='BSD',
  10. classifiers=classifiers,
  11. packages=find_packages(exclude=['tests', 'tests.*']),
  12. install_requires=install_requires,
  13. test_suite="tests",
  14. tests_require=get_requirements('test.txt'),
  15. package_data={'flower': ['templates/*', 'static/**/*', 'static/*.*']},
  16. entry_points={
  17. 'console_scripts': [
  18. 'flower = flower.__main__:main',
  19. ],
  20. 'celery.commands': [
  21. 'flower = flower.command:FlowerCommand',
  22. ],
  23. },
  24. )

  

然后将封装一个python脚本

说明flower脚本实际调用的是:

两种启动方式

  1. [celery.commands]
  2. flower = flower.command:FlowerCommand
  3.  
  4. [console_scripts]
  5. flower = flower.__main__:main

2、如何制作一个egg包以及对应的setup.py如何写呢?

2.1制作一个空的egg包目录以及setup.py文件

首先建立工程目录egg-demo,初始化一个setup.py文件:

  1. [root@typhoeus79 ice_test_m 20141022]# tree -l
  2. .
  3. `-- egg-demo
  4. `-- setup.py
  5.  
  6. 1 directory, 1 file
  7. [root@typhoeus79 ice_test_m 20141022]# more ./egg-demo/setup.py
  8. #!/usr/bin/env python
  9. #-*- coding:utf-8 -*-
  10.  
  11. from setuptools import setup
  12.  
  13. setup()

写到这里,一个空的egg配置文件就写好了。

setup的帮助文档:

  1. Help on function setup in module distutils.core:
  2.  
  3. setup(**attrs)
  4. The gateway to the Distutils: do everything your setup script needs
  5. to do, in a highly flexible and user-driven way. Briefly: create a
  6. Distribution instance; find and parse config files; parse the command
  7. line; run each Distutils command found there, customized by the options
  8. supplied to 'setup()' (as keyword arguments), in config files, and on
  9. the command line.
  10.  
  11. The Distribution instance might be an instance of a class supplied via
  12. the 'distclass' keyword argument to 'setup'; if no such class is
  13. supplied, then the Distribution class (in dist.py) is instantiated.
  14. All other arguments to 'setup' (except for 'cmdclass') are used to set
  15. attributes of the Distribution instance.
  16.  
  17. The 'cmdclass' argument, if supplied, is a dictionary mapping command
  18. names to command classes. Each command encountered on the command line
  19. will be turned into a command class, which is in turn instantiated; any
  20. class found in 'cmdclass' is used in place of the default, which is
  21. (for command 'foo_bar') class 'foo_bar' in module
  22. 'distutils.command.foo_bar'. The command class must provide a
  23. 'user_options' attribute which is a list of option specifiers for
  24. 'distutils.fancy_getopt'. Any command-line options between the current
  25. and the next command are used to set attributes of the current command
  26. object.
  27.  
  28. When the entire command-line has been successfully parsed, calls the
  29. 'run()' method on each command object in turn. This method will be
  30. driven entirely by the Distribution object (which each command object
  31. has a reference to, thanks to its constructor), and the
  32. command-specific options that became attributes of each command
  33. object.

setuptools的帮助文档:

  1. Help on package setuptools:
  2.  
  3. NAME
  4. setuptools - Extensions to the 'distutils' for large or complex distributions
  5.  
  6. FILE
  7. /usr/local/sinasrv2/lib/python2.7/site-packages/distribute-0.6.28-py2.7.egg/setuptools/__init__.py
  8.  
  9. PACKAGE CONTENTS
  10. archive_util
  11. command (package)
  12. depends
  13. dist
  14. extension
  15. package_index
  16. sandbox
  17. script template
  18. script template (dev)
  19. tests (package)

  

2.2执行命令生成egg包

python setup.py bdist_egg

setup.py可以支持很多命令:

  1. [root@typhoeus79 ice_test_m egg-demo]# python setup.py --help-commands
  2. Standard commands:
  3. build build everything needed to install
  4. build_py "build" pure Python modules (copy to build directory)
  5. build_ext build C/C++ extensions (compile/link to build directory)
  6. build_clib build C/C++ libraries used by Python extensions
  7. build_scripts "build" scripts (copy and fixup #! line)
  8. clean clean up temporary files from 'build' command
  9. install install everything from build directory
  10. install_lib install all Python modules (extensions and pure Python)
  11. install_headers install C/C++ header files
  12. install_scripts install scripts (Python or otherwise)
  13. install_data install data files
  14. sdist create a source distribution (tarball, zip file, etc.)
  15. register register the distribution with the Python package index
  16. bdist create a built (binary) distribution
  17. bdist_dumb create a "dumb" built distribution
  18. bdist_rpm create an RPM distribution
  19. bdist_wininst create an executable installer for MS Windows
  20. upload upload binary package to PyPI
  21.  
  22. Extra commands:
  23. saveopts save supplied options to setup.cfg or other config file
  24. compile_catalog compile message catalogs to binary MO files
  25. develop install package in 'development mode'
  26. easy_install Find/get/install Python packages
  27. init_catalog create a new catalog based on a POT file
  28. test run unit tests after in-place build
  29. update_catalog update message catalogs from a POT file
  30. setopt set an option in setup.cfg or another config file
  31. install_egg_info Install an .egg-info directory for the package
  32. rotate delete older distributions, keeping N newest files
  33. egg_info create a distribution's .egg-info directory
  34. alias define a shortcut to invoke one or more commands
  35. extract_messages extract localizable strings from the project code
  36. bdist_egg create an "egg" distribution

  

输出日志为:

  1. [root@typhoeus79 ice_test_m egg-demo]# python setup.py bdist_egg
  2. running bdist_egg
  3. running egg_info
  4. creating UNKNOWN.egg-info
  5. writing UNKNOWN.egg-info/PKG-INFO
  6. writing top-level names to UNKNOWN.egg-info/top_level.txt
  7. writing dependency_links to UNKNOWN.egg-info/dependency_links.txt
  8. writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
  9. reading manifest file 'UNKNOWN.egg-info/SOURCES.txt'
  10. writing manifest file 'UNKNOWN.egg-info/SOURCES.txt'
  11. installing library code to build/bdist.linux-x86_64/egg
  12. running install_lib
  13. warning: install_lib: 'build/lib' does not exist -- no Python modules to install
  14. creating build
  15. creating build/bdist.linux-x86_64
  16. creating build/bdist.linux-x86_64/egg
  17. creating build/bdist.linux-x86_64/egg/EGG-INFO
  18. copying UNKNOWN.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
  19. copying UNKNOWN.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  20. copying UNKNOWN.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  21. copying UNKNOWN.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  22. zip_safe flag not set; analyzing archive contents...
  23. creating dist
  24. creating 'dist/UNKNOWN-0.0.0-py2.6.egg' and adding 'build/bdist.linux-x86_64/egg' to it
  25. removing 'build/bdist.linux-x86_64/egg' (and everything under it)

再次查看egg-demo目录:

  1. [root@typhoeus79 ice_test_m egg-demo]# tree
  2. .
  3. |-- UNKNOWN.egg-info
  4. | |-- PKG-INFO
  5. | |-- SOURCES.txt
  6. | |-- dependency_links.txt
  7. | `-- top_level.txt
  8. |-- build
  9. | `-- bdist.linux-x86_64
  10. |-- dist
  11. | `-- UNKNOWN-0.0.0-py2.6.egg
  12. `-- setup.py

在dist文件夹下,有一个egg文件:UNKNOWN-0.0.0-py2.6.egg,这说明产蛋成功!

  1. dist/
  2. `-- UNKNOWN-0.0.0-py2.6.egg

  

egg文件是什么格式的呢?

  1. [root@typhoeus79 ice_test_m dist]# file UNKNOWN-0.0.0-py2.6.egg
  2. UNKNOWN-0.0.0-py2.6.egg: Zip archive data, at least v2.0 to extract

就是一个zip压缩包!看看其内部的结构

  1. [root@typhoeus79 ice_test_m dist]# unzip UNKNOWN-0.0.0-py2.6.egg
  2. Archive: UNKNOWN-0.0.0-py2.6.egg
  3. inflating: EGG-INFO/zip-safe
  4. inflating: EGG-INFO/top_level.txt
  5. inflating: EGG-INFO/dependency_links.txt
  6. inflating: EGG-INFO/PKG-INFO
  7. inflating: EGG-INFO/SOURCES.txt
  8. [root@typhoeus79 ice_test_m dist]# tree ./EGG-INFO/
  9. ./EGG-INFO/
  10. |-- PKG-INFO
  11. |-- SOURCES.txt
  12. |-- dependency_links.txt
  13. |-- top_level.txt
  14. `-- zip-safe

只有一个EGG-INFO文件夹,内含五个egg信息文件。

这个egg名称未知,版本0.0.0。这是因为我们在setup里什么也没有设置。

显然,这个egg什么也不能做。

2.3 在egg包增加新功能-制作demo package

在setup.py中,setup函数接收一系列属性作为配置参数。

  • name name是egg包的名称,也是寻找要打包的文件夹的名称,默认是UNKNOWN。
  • version 版本号,默认0.0.0
  • packages 这里要用到setuptools的另一个函数find_packages,顾名思义,find_packages用来将指定目录下的文件打包。
  • zip_safe 默认是False,这样在每次生成egg包时都会检查项目文件的内容,确保无误。

还有一些描述性的属性,如description,long_description,author,author_email,license,keywords,platform,url等。

  1. [root@typhoeus79 ice_test_m egg-demo]# more setup.py
  2. #!/usr/bin/env python
  3. #-*- coding:utf-8 -*-
  4.  
  5. from setuptools import setup, find_packages
  6.  
  7. setup(
  8. name = "demo",
  9. version="0.1.0",
  10. packages = find_packages(),
  11. zip_safe = False,
  12.  
  13. description = "egg test demo.",
  14. long_description = "egg test demo, haha.",
  15. author = "amoblin",
  16. author_email = "amoblin@ossxp.com",
  17.  
  18. license = "GPL",
  19. keywords = ("test", "egg"),
  20. platforms = "Independant",
  21. url = "",
  22. )

在egg-demo目录下建立和上述name名称相同的目录demo,demo目录下写__init__.py文件:

 

  1. [root@typhoeus79 ice_test_m egg-demo]# tree ./demo/
  2. ./demo/
  3. `-- __init__.py
  4.  
  5. 0 directories, 1 file
  6. [root@typhoeus79 ice_test_m egg-demo]# more ./demo/__init__.py
  7. #!/usr/bin/env python
  8. #-*- coding:utf-8 -*-
  9.  
  10. def test():
  11. print "Hello, I'm amoblin."
  12.  
  13. if __name__ == '__main__':
  14. test()

  

再次生成egg包以后查看egg包信息:

  1. [root@typhoeus79 ice_test_m egg-demo]# ll
  2. 总计 20
  3. drwxr-xr-x 4 root root 4096 10-22 14:34 build
  4. drwxr-xr-x 2 root root 4096 10-22 14:33 demo
  5. drwxr-xr-x 2 root root 4096 10-22 14:34 demo.egg-info
  6. drwxr-xr-x 2 root root 4096 10-22 14:34 dist
  7. -rw-r--r-- 1 root root 496 10-22 14:31 setup.py

 

新的egg包里面的信息如下:

  1. [root@typhoeus79 ice_test_m dist]# unzip demo-0.1.0-py2.6.egg
  2. Archive: demo-0.1.0-py2.6.egg
  3. inflating: EGG-INFO/not-zip-safe
  4. inflating: EGG-INFO/top_level.txt
  5. inflating: EGG-INFO/dependency_links.txt
  6. inflating: EGG-INFO/PKG-INFO
  7. inflating: EGG-INFO/SOURCES.txt
  8. inflating: demo/__init__.pyc
  9. inflating: demo/__init__.py

  

现在可以安装了体验一下!!

  1. [root@typhoeus79 ice_test_m egg-demo]# python setup.py install
  2. running install
  3. running bdist_egg
  4. running egg_info
  5. writing demo.egg-info/PKG-INFO
  6. writing top-level names to demo.egg-info/top_level.txt
  7. writing dependency_links to demo.egg-info/dependency_links.txt
  8. reading manifest file 'demo.egg-info/SOURCES.txt'
  9. writing manifest file 'demo.egg-info/SOURCES.txt'
  10. installing library code to build/bdist.linux-x86_64/egg
  11. running install_lib
  12. running build_py
  13. creating build/bdist.linux-x86_64/egg
  14. creating build/bdist.linux-x86_64/egg/demo
  15. copying build/lib/demo/__init__.py -> build/bdist.linux-x86_64/egg/demo
  16. byte-compiling build/bdist.linux-x86_64/egg/demo/__init__.py to __init__.pyc
  17. creating build/bdist.linux-x86_64/egg/EGG-INFO
  18. copying demo.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
  19. copying demo.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  20. copying demo.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  21. copying demo.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO
  22. copying demo.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
  23. creating 'dist/demo-0.1.0-py2.6.egg' and adding 'build/bdist.linux-x86_64/egg' to it
  24. removing 'build/bdist.linux-x86_64/egg' (and everything under it)
  25. Processing demo-0.1.0-py2.6.egg
  26. creating /usr/lib/python2.6/site-packages/demo-0.1.0-py2.6.egg
  27. Extracting demo-0.1.0-py2.6.egg to /usr/lib/python2.6/site-packages
  28. Adding demo 0.1.0 to easy-install.pth file
  29.  
  30. Installed /usr/lib/python2.6/site-packages/demo-0.1.0-py2.6.egg
  31. Processing dependencies for demo==0.1.0
  32. Finished processing dependencies for demo==0.1.0

  

安装完毕!接下来我们就可以直接通过import来使用啦!

  1. >>> from demo import test
  2. >>> help(test)
  3.  
  4. >>> test()
  5. Hello, I'm amoblin.

  

源程序都放在src目录下,所以接下来将demo文件夹移动到src里。但这样也要修改setup.py文件,修改find_packages函数中参数为’src’,同时增加package_dir参数:

  1. packages=find_packages('src'),
  2. package_dir = {'':'src'}

这样告诉setuptools在src目录下找包,而不是原来默认的工程根目录。

2.4如何删除egg包

找到package放的位置

  1. >>> print sys.path[1]
  2. /usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg

存在这个egg包  

  1. [root@typhoeus79 ice_test_m site-packages]# ll /usr/lib/python2.6/site-packages |grep demo
  2. drwxr-xr-x 4 root root 4096 10-22 14:36 demo-0.1.0-py2.6.egg
  3. [root@typhoeus79 ice_test_m site-packages]# cat easy-install.pth|grep demo
  4. ./demo-0.1.0-py2.6.egg

  

卸载egg文件很简单,首先将包含此egg的行从easy-install.pth中删除,然后删除egg文件夹即可。

3、参考资料

1、http://www.cnblogs.com/itech/archive/2011/02/13/1953268.html

2、http://zhiwei.li/text/2011/06/load_entry_point%E5%92%8Csetup-egg/

3、http://django-china.cn/topic/90/

4、http://blog.habnab.it/blog/2013/07/21/python-packages-and-you/

Python的egg包的更多相关文章

  1. python的egg包的安装和制作]

    Defining Python Source Code Encodings Python egg 的安装 egg文件制作与安装 2011-06-10 14:22:50|  分类: python |   ...

  2. Python中的包ImportError

    前言 Python中的包给我提供了很好的代码组织,相似的功能模块放在同一个包内,不仅代码结构清晰,而且调用起来也比较方便(可以用*导入) 但是,我们在刚开始使用Python包的时候总是会遇到导入错误& ...

  3. Python黑帽编程1.3 Python运行时与包管理工具

    Python黑帽编程1.3  Python运行时与包管理工具 0.1  本系列教程说明 本系列教程,采用的大纲母本为<Understanding Network Hacks Attack and ...

  4. python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法?

    python中引入包的时候报错:import unittestimport smtplibimport timeimport osimport sysimp.reload(sys)sys.setdef ...

  5. Python之扩展包安装

    读者朋友,在比较新的版本(Python 2 >=2.7.9 or Python 3 >=3.4)中,pip或者easy_install 扩展包命令已经默认安装(可查看   你的安装目录\p ...

  6. [resource]23个python的机器学习包

    23个python的机器学习包,从常见的scikit-learn, pylearn2,经典的matlab替代orange, 到最新最酷的Theano(深度学习)和torch 7 (well,其实lua ...

  7. Python学习 之 包和模块

    1.rpm -ql python #查看python在计算机中安装了哪些文件 2.模块是一个可以导入的Python脚本文件 包是一堆按目录组织的模块和子包,目录下的__init__.py文件存放了包的 ...

  8. 使用pip install 或者easy_install安装Python的各种包出现cc failed with exit status 1

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  9. 繁简转换OpenCC,autogb 和 autob5,iconv,python的jianfan包

    OpenCC OpenCC 是跨平台.多语言的开放中文转换库,除了基本的简繁转换功能外,用户还可以选择对不同用词习惯和异体字的处理方式. OpenCC 还提供方便的网页转换界面. OpenOffice ...

随机推荐

  1. Linux vi 退出&保存/不保存

    无论是否退出 vi,均可保存所做的工作.按 ESC 键,确定 vi 是否处于命令模式. 操作   键入 保存,但不退出vi                          :w 保存并退出vi    ...

  2. 学习PID

    最近在想自己的文章有些是不是写的太难以理解了呢.........竟然好多人看了还是会直接问我很多问题....... 其实PID哈靠自己想像就能自己写出来自己的代码,也许是网上的讲的太过的高深什么积分微 ...

  3. PHP+nginx 线上服务研究(一)

    一. 基本介绍 OpenResty® 是一个基于Nginx和Lua的高性能Web平台,其内部集成了大量精良的Lua库.第三方模块以及大多数的依赖项.用于方便搭建能够处理超高并发.扩展性极高的动态Web ...

  4. Laplace(拉普拉斯)先验与L1正则化

    Laplace(拉普拉斯)先验与L1正则化 在之前的一篇博客中L1正则化及其推导推导证明了L1正则化是如何使参数稀疏化人,并且提到过L1正则化如果从贝叶斯的观点看来是Laplace先验,事实上如果从贝 ...

  5. coursera_poj_魔兽世界终结版

    五个下午的时间!!!!终于过了!!有史以来做的最复杂的一个题这是我迄今为止做的最复杂也最具有挑战的一个oj作业.虽然之前做过比这个规模一些作业项目,但是往往有简单的模块框架,模块之前的关系也只是有些简 ...

  6. Android 圆角的效果实现

    Android 自定义ImageView实现圆角图片昨天给学生布置作业,写微信首页,也就是聊天的界面,listView里的item中联系人的头像是圆角的,图形界面如下: 那么我就仔细研究了圆角的具体实 ...

  7. MongoDB关系与数据库引用

    MongoDB关系: MongoDB 的关系表示多个文档之间在逻辑上的相互联系.文档间可以通过嵌入和引用来建立联系. 1. 嵌入关系: 形式:把一个文档嵌入到另一个文档中. 优点:数据保存在单一的文档 ...

  8. Hibernate映射类型

  9. Java基础笔记9

    super关键字 表示父类对象. 1.可以调用父类中被重写的方法. 2.还有调用父类中的构造方法.放在子类构造方法的第一行. 不能和this关键字同时出现. final关键字 1.修饰属性.表示常量. ...

  10. Spring容器组建注解@Component和Resouces实现完全注解配置

    @Resource和@Component实现零XML配置 1.@Resource的注解: @Resource是J2EE的注解.意思是说在容器里面找相应的资源.也可以通过name属性指定它name的资源 ...