国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
關(guān)于python中的setup.py

from 

http://blog.csdn.net/xluren/article/details/41114779

2014.11

http://lingxiankong.github.io/blog/2013/12/23/Python-setup/

感謝作者,解決了我一個大問題

前言

其實(shí)對于setup.py和setup.cfg的關(guān)注是從OpenStack的源碼包中開始的,OpenStack每個組件的發(fā)布時都是一個tar.gz包,同樣,我們直接從github上clone代碼后也會發(fā)現(xiàn)兩個文件的存在。當(dāng)閱讀Nova或Ceilometer(其他組件可能也會涉及)的代碼時,發(fā)現(xiàn)setup.cfg中內(nèi)容對于代碼的理解有很大的影響。那么,到底setup.py和setup.cfg是干什么的?

setup.py

我們從例子開始。假設(shè)你要分發(fā)一個叫foo的模塊,文件名foo.py,那么setup.py內(nèi)容如下:

  1. from distutils.core import setup
  2. setup(name='foo',
  3. version='1.0',
  4. py_modules=['foo'],
  5. )

然后,運(yùn)行python setup.py sdist為模塊創(chuàng)建一個源碼包

  1. root@network:/kong/setup# python setup.py sdist
  2. running sdist
  3. running check
  4. warning: check: missing required meta-data: url
  5. warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) must be supplied
  6. warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list)
  7. warning: sdist: standard file not found: should have one of README, README.txt
  8. writing manifest file 'MANIFEST'
  9. creating foo-1.0
  10. making hard links in foo-1.0...
  11. hard linking foo.py -> foo-1.0
  12. hard linking setup.py -> foo-1.0
  13. creating dist
  14. Creating tar archive
  15. removing 'foo-1.0' (and everything under it)

在當(dāng)前目錄下,會創(chuàng)建dist目錄,里面有個文件名為foo-1.0.tar.gz,這個就是可以分發(fā)的包。使用者拿到這個包后,解壓,到foo-1.0目錄下執(zhí)行:python setup.py install,那么,foo.py就會被拷貝到python類路徑下,可以被導(dǎo)入使用。

  1. root@network:/kong/setup/dist/foo-1.0# python setup.py install
  2. running install
  3. running build
  4. running build_py
  5. creating build
  6. creating build/lib.linux-x86_64-2.7
  7. copying foo.py -> build/lib.linux-x86_64-2.7
  8. running install_lib
  9. copying build/lib.linux-x86_64-2.7/foo.py -> /usr/local/lib/python2.7/dist-packages
  10. byte-compiling /usr/local/lib/python2.7/dist-packages/foo.py to foo.pyc
  11. running install_egg_info
  12. Removing /usr/local/lib/python2.7/dist-packages/foo-1.0.egg-info
  13. Writing /usr/local/lib/python2.7/dist-packages/foo-1.0.egg-info
  14. root@network:/kong/setup/dist/foo-1.0# ll /usr/local/lib/python2.7/dist-packages/foo
  15. foo-1.0.egg-info foo.py foo.pyc

對于Windows,可以執(zhí)行python setup.py bdist_wininst生成一個exe文件;若要生成RPM包,執(zhí)行python setup.py bdist_rpm,但系統(tǒng)必須有rpm命令的支持??梢赃\(yùn)行下面的命令查看所有格式的支持:

  1. root@network:/kong/setup# python setup.py bdist --help-formats
  2. List of available distribution formats:
  3. --formats=rpm RPM distribution
  4. --formats=gztar gzip'ed tar file
  5. --formats=bztar bzip2'ed tar file
  6. --formats=ztar compressed tar file
  7. --formats=tar tar file
  8. --formats=wininst Windows executable installer
  9. --formats=zip ZIP file
  10. --formats=msi Microsoft Installer

setup函數(shù)還有一些參數(shù):

1、packages
告訴Distutils需要處理那些包(包含__init__.py的文件夾)
2、package_dir
告訴Distutils哪些目錄下的文件被映射到哪個源碼包。一個例子:package_dir = {'': 'lib'},表示“root package”中的模塊都在lib目錄中。
3、ext_modules
是一個包含Extension實(shí)例的列表,Extension的定義也有一些參數(shù)。
4、ext_package
定義extension的相對路徑
5、requires
定義依賴哪些模塊
6、provides
定義可以為哪些模塊提供依賴
7、scripts
指定python源碼文件,可以從命令行執(zhí)行。在安裝時指定--install-script
8、package_data
通常包含與包實(shí)現(xiàn)相關(guān)的一些數(shù)據(jù)文件或類似于readme的文件。如果沒有提供模板,會被添加到MANIFEST文件中。
9、data_files
指定其他的一些文件(如配置文件)

  1. setup(...,
  2. data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
  3. ('config', ['cfg/data.cfg']),
  4. ('/etc/init.d', ['init-script'])]
  5. )

規(guī)定了哪些文件被安裝到哪些目錄中。如果目錄名是相對路徑,則是相對于sys.prefixsys.exec_prefix的路徑。如果沒有提供模板,會被添加到MANIFEST文件中。

執(zhí)行sdist命令時,默認(rèn)會打包哪些東西呢?

  • 所有由py_modulespackages指定的源碼文件
  • 所有由ext_moduleslibraries指定的C源碼文件
  • scripts指定的腳本文件
  • 類似于test/test*.py的文件
  • README.txt或README,setup.py,setup.cfg
  • 所有package_datadata_files指定的文件

還有一種方式是寫一個manifest template,名為MANIFEST.in,定義如何生成MANIFEST文件,內(nèi)容就是需要包含在分發(fā)包中的文件。一個MANIFEST.in文件如下:

  1. include *.txt
  2. recursive-include examples *.txt *.py
  3. prune examples/sample?/build

setup.cfg

setup.cfg提供一種方式,可以讓包的開發(fā)者提供命令的默認(rèn)選項(xiàng),同時為用戶提供修改的機(jī)會。對setup.cfg的解析,是在setup.py之后,在命令行執(zhí)行前。

setup.cfg文件的形式類似于

  1. [command]
  2. option=value
  3. ...

其中,command是Distutils的命令參數(shù),option是參數(shù)選項(xiàng),可以通過python setup.py --help build_ext方式獲取。

需要注意的是,比如一個選項(xiàng)是--foo-bar,在setup.cfg中必須改成foo_bar的格式

符合Distutils2的setup.cfg有些不同。包含一些sections:
1、global
定義Distutils2的全局選項(xiàng),可能包含commands,compilers,setup_hook(定義腳本,在setup.cfg被讀取后執(zhí)行,可以修改setup.cfg的配置)
2、metadata
3、files

  • packages_root:根目錄
  • packages
  • modules
  • scripts
  • extra_files

4、command sections

Setuptools

上面的setup.py和setup.cfg都是遵循python標(biāo)準(zhǔn)庫中的Distutils,而setuptools工具針對Python官方的distutils做了很多針對性的功能增強(qiáng),比如依賴檢查,動態(tài)擴(kuò)展等。很多高級功能我就不詳述了,自己也沒有用過,等用的時候再作補(bǔ)充。

一個典型的遵循setuptools的腳本:

  1. from setuptools import setup, find_packages
  2. setup(
  3. name = "HelloWorld",
  4. version = "0.1",
  5. packages = find_packages(),
  6. scripts = ['say_hello.py'],
  7. # Project uses reStructuredText, so ensure that the docutils get
  8. # installed or upgraded on the target machine
  9. install_requires = ['docutils>=0.3'],
  10. package_data = {
  11. # If any package contains *.txt or *.rst files, include them:
  12. '': ['*.txt', '*.rst'],
  13. # And include any *.msg files found in the 'hello' package, too:
  14. 'hello': ['*.msg'],
  15. },
  16. # metadata for upload to PyPI
  17. author = "Me",
  18. author_email = "me@example.com",
  19. description = "This is an Example Package",
  20. license = "PSF",
  21. keywords = "hello world example examples",
  22. url = "http://example.com/HelloWorld/", # project home page, if any
  23. # could also include long_description, download_url, classifiers, etc.
  24. )

如何讓一個egg可被執(zhí)行?

  1. setup(
  2. # other arguments here...
  3. entry_points = {
  4. 'setuptools.installation': [
  5. 'eggsecutable = my_package.some_module:main_func',
  6. ]
  7. }
  8. )

如何定義一個可選特性?

  1. setup(
  2. name="Project-A",
  3. ...
  4. extras_require = {
  5. 'PDF': ["ReportLab>=1.2", "RXP"],
  6. 'reST': ["docutils>=0.3"],
  7. }
  8. )

特性如何使用呢?需要與entry points結(jié)合使用:

  1. setup(
  2. name="Project-A",
  3. ...
  4. entry_points = {
  5. 'console_scripts': [
  6. 'rst2pdf = project_a.tools.pdfgen [PDF]',
  7. 'rst2html = project_a.tools.htmlgen',
  8. # more script entry points ...
  9. ],
  10. }
  11. )

或者被其他project依賴:install_requires = ["Project-A[PDF]"]

插件式開發(fā)

我想大家最熟悉的就是這個特性了吧。比如一個博客系統(tǒng)想用不同的插件支持不同的語言輸出格式,那么就可以定義一個“entry point group”,不同的插件就可以注冊“entry point”,插件注冊的示例:

  1. setup(
  2. # ...
  3. entry_points = {'blogtool.parsers': ['.rst = some_module:a_func']}
  4. )
  5. # 或者
  6. setup(
  7. # ...
  8. entry_points = """
  9. [blogtool.parsers]
  10. .rst = some.nested.module:SomeClass.some_classmethod [reST]
  11. """,
  12. extras_require = dict(reST = "Docutils>=0.3.5")
  13. )

Setuptools中的dependency_links

Setuptools有一個功能叫做 dependency_links

from setuptools import setup

  1. setup(
  2. # ...
  3. dependency_links = [
  4. "http://packages.example.com/snapshots/",
  5. "http://example2.com/p/bar-1.0.tar.gz",
  6. ],
  7. )

這一功能除去了依賴的抽象特性,直接把依賴的獲取url標(biāo)在了setup.py里。就像在Go語言中修改依賴包一樣,我們只需要修改依賴鏈中每個包的 dependency_links 。

管理依賴

我們寫依賴聲明的時候需要在 setup.py 中寫好抽象依賴(install_requires),在 requirements.txt 中寫好具體的依賴,但是我們并不想維護(hù)兩份依賴文件,這樣會讓我們很難做好同步。 requirements.txt 可以更好地處理這種情況,我們可以在有 setup.py 的目錄里寫下一個這樣的 requirements.txt

  1. --index https://pypi.python.org/simple/
  2. -e .

這樣 pip install -r requirements.txt 可以照常工作,它會先安裝該文件路徑下的包,然后繼續(xù)開始解析抽象依賴,結(jié)合 --index 選項(xiàng)后轉(zhuǎn)換為具體依賴然后再安裝他們。

這個辦法可以讓我們解決一種類似這樣的情形:比如你有兩個或兩個以上的包在一起開發(fā)但是是分開發(fā)行的,或者說你有一個尚未發(fā)布的包并把它分成了幾個部分。如果你的頂層的包 依然僅僅按照“名字”來依賴的話,我們依然可以使用 requirements.txt 來安裝開發(fā)版本的依賴包:

  1. --index https://pypi.python.org/simple/
  2. -e https://github.com/foo/bar.git#egg=bar
  3. -e .

這會首先從 https://github.com/foo/bar.Git 來安裝包 bar , 然后進(jìn)行到第二行 -e . ,開始安裝 setup 中的抽象依賴,但是包 bar 已經(jīng)安裝過了, 所以 pip 會跳過安裝。

Differences between distribute, distutils, setuptools and distutils2

Distutils is the standard tool used for packaging. It works rather well for simple needs, but is limited and not trivial to extend.

Setuptools is a project born from the desire to fill missing distutils functionality and explore new directions. In some subcommunities, it’s a de facto standard. It uses monkey-patching and magic that is frowned upon by Python core developers.

Distribute is a fork of Setuptools that was started by developers feeling that its development pace was too slow and that it was not possible to evolve it. Its development was considerably slowed when distutils2 was started by the same group. 2013-August update: distribute is merged back into setuptools and discontinued.

Distutils2 is a new distutils library, started as a fork of the distutils codebase, with good ideas taken from setup tools (of which some were thoroughly discussed in PEPs), and a basic installer inspired by pip. The actual name you use to import Distutils2 is packaging in the Python 3.3+ standard library, or distutils2 in 2.4+ and 3.1–3.2. (A backport will be available soon.) Distutils2 did not make the Python 3.3 release, and it was put on hold.

PBR

pbr是setuptools的輔助工具,最初是為OpenStack開發(fā)(https://launchpad.net/pbr),基于d2to1。

A library for managing setuptools packaging needs in a consistent manner.

pbr會讀取和過濾setup.cfg中的數(shù)據(jù),然后將解析后的數(shù)據(jù)提供給setup.py作為參數(shù)。包含如下功能:
1、從git中獲取Version、AUTHORS and ChangeLog信息
2、Sphinx Autodoc。pbr會掃描project,找到所有模塊,生成stub files
3、Requirements。pbr會讀取requirements.txt,生成setup函數(shù)需要的install_requires/tests_require/dependency_links

這里需要注意,在requirements.txt文件的頭部可以使用:--index https://pypi.python.org/simple/,這一行把一個抽象的依賴聲明如 requests==1.2.0 轉(zhuǎn)變?yōu)橐粋€具體的依賴聲明 requests 1.2.0 from pypi.python.org/simple/

4、long_description。從README.rst, README.txt or README file中生成long_description參數(shù)

使用pbr很簡單:

  1. from setuptools import setup
  2. setup(
  3. setup_requires=['pbr'],
  4. pbr=True,
  5. )

使用pbr時,setup.cfg中有一些配置。在[files]中,有三個key:
packages:指定需要包含的包,行為類似于setuptools.find_packages
namespace_packages:指定namespace packages
data_files: 指定目的目錄和源文件路徑,一個示例:

  1. [files]
  2. data_files =
  3. etc/pbr = etc/pbr/*
  4. etc/neutron =
  5. etc/api-paste.ini
  6. etc/dhcp-agent.ini
  7. etc/init.d = neutron.init

[entry_points]段跟setuptools的方式相同。

Babel

A collection of tools for internationalizing Python applications

Babel是 Python 的一個國際化工具包,提供了對distutils或setuptools的支持,包含一些命令。

1、compile_catalog
類似于msgfmt工具,takes a message catalog from a PO file and compiles it to a binary MO file.

  1. $ ./setup.py compile_catalog --directory foobar/locale --locale pt_BR
  2. running compile_catalog
  3. compiling catalog to foobar/locale/pt_BR/LC_MESSAGES/messages.mo

2、extract_messages
類似于xgettext,it can extract localizable messages from a variety of difference source files, and generate a PO (portable object) template file from the collected messages.

  1. $ ./setup.py extract_messages --output-file foobar/locale/messages.pot
  2. running extract_messages
  3. extracting messages from foobar/__init__.py
  4. extracting messages from foobar/core.py
  5. ...
  6. writing PO template file to foobar/locale/messages.pot

3、update_catalog
類似于msgmerge,it updates an existing translations catalog based on a PO template file (POT).

setup.py和pip

表面上,python setup.py installpip install都是用來安裝python包的,實(shí)際上,pip提供了更多的特性,更易于使用。體現(xiàn)在以下幾個方面:

  • pip會自動下載依賴,而如果使用setup.py,則需要手動搜索和下載;
  • pip會自動管理包的信息,使卸載/更新更加方便和容易,使用pip uninstall即可。而使用setup.py,必須手動刪除,有時容易出錯。
  • pip提供了對virtualenv更好的整合。

結(jié)語

OK,講了這么多瑣碎的東西,現(xiàn)在去看看Nova或Ceilometer的setup腳本,是不是一下清晰了很多?!但說實(shí)話,setup.py的使用,我還不能講的特別清楚,需要在后續(xù)的實(shí)戰(zhàn)中學(xué)習(xí)。


參考文檔:
http://docs.python.org/2/distutils/introduction.html
http://pythonhosted.org/setuptools/


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
python技巧26[python的egg包的安裝和制作]
python打包工具distutils、setuptools分析
Python包的大總結(jié)!全面學(xué)習(xí)Python包:包的構(gòu)建與分發(fā)
Python深入:Distutils發(fā)布Python模塊
可愛的 Python: 使用 setuptools 孵化 Python egg
Python中在setup.py使用源碼版本控制元數(shù)據(jù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服