Python 之打包工具 setup.py

1. 為什么需要對項目分發打包?

平常我們習慣了使用 pip 來安裝一些第三方模塊,這個安裝過程之所以簡單,是因為模塊開發者為我們默默地為我們做了所有繁雜的工作,而這個過程就是 打包

打包,就是將你的源代碼進一步封裝,并且將所有的項目部署工作都事先安排好,這樣使用者拿到后即裝即用,不用再操心如何部署的問題(如果你不想對照著一堆部署文檔手工操作的話)。

不管你是在工作中,還是業余準備自己寫一個可以上傳到 PyPI 的項目,你都要學會如何打包你的項目。

Python 發展了這么些年了,項目打包工具也已經很成熟了。他們都有哪些呢?

你可能聽過 distutilsdistutils2setuptools等等,好像很熟悉,卻又很陌生,他們都是什么關系呢?

2. 包分發的始祖:distutils

distutils 是 Python 的一個標準庫,從命名上很容易看出它是一個分發(distribute)工具(utlis),它是 Python 官方開發的一個分發打包工具,所有后續的打包工具,全部都是基于它進行開發的。

distutils 的精髓在于編寫 setup.py,它是模塊分發與安裝的指導文件。

那么如何編寫 setup.py 呢?我會在后面進行詳細的解析。

你有可能沒寫過 setup.py ,但你絕對使用過 setup.py 來做一些事情,比如下面這條命令,我們經常用它來進行模塊的安裝。

$ python setup.py install

這樣的安裝方法是通過源碼安裝,與之對應的是通過二進制軟件包的安裝,同樣我也會在后面進行介紹。

3. 分發工具升級:setuptools

setuptools 是 distutils 增強版,不包括在標準庫中。其擴展了很多功能,能夠幫助開發者更好的創建和分發 Python 包。大部分 Python 用戶都會使用更先進的 setuptools 模塊。

distribute,或許你在其他地方也見過它,這里也提一下。

distribute 是 setuptools 有一個分支版本,分支的原因可能是有一部分開發者認為 setuptools 開發太慢了。但現在,distribute 又合并回了 setuptools 中。因此,我們可以認為它們是同一個東西。

還有一個大包分發工具是 distutils2,其試圖嘗試充分利用distutils,detuptools 和 distribute 并成為 Python 標準庫中的標準工具。但該計劃并沒有達到預期的目的,且已經是一個廢棄的項目。

因此,setuptools 是一個優秀的,可靠的 Python 包安裝與分發工具。

那么如何在一個干凈的環境中安裝 setuptools 呢?

主要有兩種方法:

  • 源碼安裝:在 https://pypi.org/project/setuptools/#files 中下載 zip 包 解壓執行 python setup.py install 安裝
  • 通過引導程序安裝:下載引導程序,它可以用來下載或者更新最新版本的 setuptools
$ wget http://peak.telecommunity.com/dist/ez_setup.py# 安裝
$ python ez_setup.py# 更新,以下兩種任選
$ python ez_setup.py –U setuptools
$ pip install -U setuptools

4. easy_install 使用指南

當你安裝完 setuptools 后,就擁有了一個叫做 easy_install 的第三方管理工具,這也是它區分于 distutils 的一大改進。

這里簡單介紹一下它的用法,雖然它已經用得非常少了。

先是包的安裝

# 通過包名,從PyPI尋找最新版本,自動下載、編譯、安裝
$ easy_install pkg_name# 通過包名從指定下載頁尋找鏈接來安裝或升級包
$ easy_install -f http://pythonpaste.org/package_index.html # 指定線上的包地址安裝
$ easy_install http://example.com/path/to/MyPackage-1.2.3.tgz# 從本地的 .egg 文件安裝
$ easy_install xxx.egg# 在安裝時你可以添加額外的參數
指定安裝目錄:--install-dir=DIR, -d DIR
指定用戶安裝:--user

再者是包的升級

# 從 pypi 中搜索并升級包
$ easy_install --upgrade pkg_name# 指定版本進行升級
$ easy_install "SomePackage==2.0"

最后是包的刪除

$ easy_install -m pkg_name

需要注意的是,這樣的刪除,僅是在 easy-install.pth 文件中刪除,使其不能在 python 中使用 這個模塊,但實際的包還在你的電腦中,若要刪除徹底,需要你手動刪除相關的 .egg 及 其他文件。

默認情況下,easy_install 只會從 pypi 上下載相關軟件包,由于這個源在國外,下載包的速度并不理想,使用過pip的朋友自然會想,easy_install 是否能指定源進行安裝呢?

答案是,可以的。

編輯配置文件 /root/.pydistutils.cfg

[easy_install]
index-url=http://mirrors.aliyun.com/pypi/simple/
find-links=http://mirrors.aliyun.com/pypi/simple/

以上僅介紹了 easy_install 的一些常用的方法,想要了解更多,你可以點擊官方文檔:https://setuptools.readthedocs.io/en/latest/easy_install.html

總結一句:setuptools 是官方提供的一個專業用于包分發的工具,若只從安裝的角度來看,它的功能確實簡單。它更大的意義是對包的分發很有用,定制化程序非常高,我們現在也還在用它進行版本包的發布。

5. 源碼包與二進制包什么區別?

Python 包的分發可以分為兩種:

1、以源碼包的方式發布

源碼包安裝的過程,是先解壓,再編譯,最后才安裝,所以它是跨平臺的,由于每次安裝都要進行編譯,相對二進包安裝方式來說安裝速度較慢。

源碼包的本質是一個壓縮包,其常見的格式有:

格式后綴
zip.zip
gztar.tar.gz
bztar.tar.bz2
ztar.tra.Z
tar.tar

2、以二進制包形式發布

二進制包的安裝過程省去了編譯的過程,直接進行解壓安裝,所以安裝速度較源碼包來說更快。

由于不同平臺的編譯出來的包無法通用,所以在發布時,需事先編譯好多個平臺的包。

二進制包的常見格式有:

格式后綴
egg.egg
wheel.whl

6. eggs 與 wheels 有什么區別?

Egg 格式是由 setuptools 在 2004 年引入,而 Wheel 格式是由 PEP427 在 2012 年定義。Wheel 的出現是為了替代 Egg,它的本質是一個zip包,其現在被認為是 Python 的二進制包的標準格式。

以下是 Wheel 和 Egg 的主要區別:

  • Wheel 有一個官方的 PEP427 來定義,而 Egg 沒有 PEP 定義
  • Wheel 是一種分發格式,即打包格式。而 Egg 既是一種分發格式,也是一種運行時安裝的格式,并且是可以被直接 import
  • Wheel 文件不會包含 .pyc 文件
  • Wheel 使用和 PEP376 兼容的 .dist-info 目錄,而 Egg 使用 .egg-info 目錄
  • Wheel 有著更豐富的命名規則。
  • Wheel 是有版本的。每個 Wheel 文件都包含 wheel 規范的版本和打包的實現
  • Wheel 在內部被 sysconfig path type 管理,因此轉向其他格式也更容易

wheel 包可以通過 pip 來安裝,只不過需要先安裝 wheel 模塊,然后再使用 pip 的命令。

$ pip install wheel
$ pip wheel --wheel-dir=/local/wheels pkg

7. 超詳細講解 setup.py 的編寫?

打包分發最關鍵的一步是編寫 setup.py 文件。

以下是一個 setup.py 簡單的使用示例

from setuptools import setup, find_packagessetup(# 指定項目名稱,我們在后期打包時,這就是打包的包名稱,當然打包時的名稱可能還會包含下面的版本號喲~name="mytest",# 指定版本號version="1.0",author="flp",author_email="flepeng@163.com",# 這是對當前項目的一個描述description="這只是一次測試",# 項目主頁url="http://iswbm.com/", # 你要安裝的包,通過 setuptools.find_packages 找到當前目錄下有哪些包packages=find_packages()# 指定包名,即你需要打包的包名稱,要實際在你本地存在喲,它會將指定包名下的所有"*.py"文件進行打包喲,但不會遞歸去拷貝所有的子包內容。# 綜上所述,我們如果想要把一個包的所有"*.py"文件進行打包,應該在packages列表寫下所有包的層級關系喲~這樣就開源將指定包路徑的所有".py"文件進行打包!packages=['devops', "devops.dev", "devops.ops"],
)

setup 函數常用的參數如下:

參數說明
name包名稱
version包版本
author程序的作者
author_email程序的作者的郵箱地址
maintainer維護者
maintainer_email維護者的郵箱地址
url程序的官網地址
license程序的授權信息
description程序的簡單描述
long_description程序的詳細描述
platforms程序適用的軟件平臺列表
classifiers程序的所屬分類列表
keywords程序的關鍵字列表
packages需要處理的包目錄(通常為包含 init.py 的文件夾)
py_modules需要打包的 Python 單文件列表
download_url程序的下載地址
cmdclass添加自定義命令
package_data指定包內需要包含的數據文件
include_package_data自動包含包內所有受版本控制(cvs/svn/git)的數據文件
exclude_package_data當 include_package_data 為 True 時該選項用于排除部分文件
data_files打包時需要打包的數據文件,如圖片,配置文件等
ext_modules指定擴展模塊
scripts指定可執行腳本,安裝時腳本會被安裝到系統 PATH 路徑下
package_dir指定哪些目錄下的文件被映射到哪個源碼包
entry_points動態發現服務和插件,下面詳細講
python_requires指定運行時需要的Python版本
requires指定依賴的其他包
provides指定可以為哪些模塊提供依賴
install_requires
extras_require當前包的高級/額外特性需要依賴的分發包
tests_require在測試時需要使用的依賴包
setup_requires指定運行 setup.py 文件本身所依賴的包
dependency_links指定依賴包的下載地址
zip_safe不壓縮包,而是以目錄的形式安裝

更多參數可見:https://setuptools.readthedocs.io/en/latest/setuptools.html

接下來,我將慢慢擴充這個setup函數,增加更多的參數,以便你能理解setup函數能做哪些事情。

程序分類信息

classifiers 參數說明包的分類信息。所有支持的分類列表見:https://pypi.org/pypi?%3Aaction=list_classifiers

示例:

from setuptools import setup, find_packagessetup(classifiers = [# 發展時期,常見的如下#   3 - Alpha#   4 - Beta#   5 - Production/Stable'Development Status :: 3 - Alpha',# 開發的目標用戶'Intended Audience :: Developers',# 屬于什么類型'Topic :: Software Development :: Build Tools',# 許可證信息'License :: OSI Approved :: MIT License',# 目標 Python 版本'Programming Language :: Python :: 2','Programming Language :: Python :: 2.7','Programming Language :: Python :: 3','Programming Language :: Python :: 3.3','Programming Language :: Python :: 3.4','Programming Language :: Python :: 3.5',]
)

關于文件的分發

from setuptools import setup, find_packagessetup(name="mytest",version="1.0",author="wangbm",author_email="wongbingming@163.com",description="Learn to Pack Python Module",url="http://iswbm.com/", packages=find_packages(),# 安裝過程中,需要安裝的靜態文件,如配置文件、service文件、圖片等data_files=[('', ['conf/*.conf']),('/usr/lib/systemd/system/', ['bin/*.service']),],# 希望被打包的文件package_data={'':['*.txt'],'bandwidth_reporter':['*.txt']},# 不打包某些文件exclude_package_data={'bandwidth_reporter':['*.txt']}
)

除了以上的參數配置之外,還可以使用一個叫做 MANIFEST.in 的文件,來控制文件的分發。

如下這是一個 MANIFEST.in 的樣例:

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

這些配置,規定了如下幾點

  • 所有根目錄下的以 txt 為后綴名的文件,都會分發
  • 根目錄下的 examples 目錄 和 txt、py文件都會分發
  • 路徑匹配上 examples/sample?/build 不會分發

MANIFEST.in 需要放在和 setup.py 同級的頂級目錄下,setuptools 會自動讀取該文件。

關于依賴包下載安裝

from setuptools import setup, find_packagessetup(...# 表明當前模塊依賴哪些包,若環境中沒有,則會從pypi中下載安裝install_requires=['docutils>=0.3'],# setup.py 本身要依賴的包,這通常是為一些setuptools的插件準備的配置# 這里列出的包,不會自動安裝。setup_requires=['pbr'],# 僅在測試時需要使用的依賴,在正常發布的代碼中是沒有用的。# 在執行python setup.py test時,可以自動安裝這三個庫,確保測試的正常運行。tests_require=['pytest>=3.3.1','pytest-cov>=2.5.1',],# 用于安裝setup_requires或tests_require里的軟件包# 這些信息會寫入egg的 metadata 信息中dependency_links=["http://example2.com/p/foobar-1.0.tar.gz",],# install_requires 在安裝模塊時會自動安裝依賴包# 而 extras_require 不會,這里僅表示該模塊會依賴這些包# 但是這些包通常不會使用到,只有當你深度使用模塊時,才會用到,這里需要你手動安裝extras_require={'PDF':  ["ReportLab>=1.2", "RXP"],'reST': ["docutils>=0.3"],}
)

關于 install_requires, 有以下五種常用的表示方法:

  1. 'argparse',只包含包名。 這種形式只檢查包的存在性,不檢查版本。 方便,但不利于控制風險。
  2. 'setuptools==38.2.4',指定版本。 這種形式把風險降到了最低,確保了開發、測試與部署的版本一致,不會出現意外。 缺點是不利于更新,每次更新都需要改動代碼。
  3. 'docutils >= 0.3',這是比較常用的形式。 當對某個庫比較信任時,這種形式可以自動保持版本為最新。
  4. 'Django >= 1.11, != 1.11.1, <= 2',這是比較復雜的形式。 如這個例子,保證了Django的大版本在1.11和2之間,也即1.11.x;并且,排除了已知有問題的版本1.11.1(僅舉例)。 對于一些大型、復雜的庫,這種形式是最合適的。
  5. 'requests[security, socks] >= 2.18.4',這是包含了額外的可選依賴的形式。 正常安裝requests會自動安裝它的install_requires中指定的依賴,而不會安裝securitysocks這兩組依賴。 這兩組依賴是定義在它的extras_require中。 這種形式,用在深度使用某些庫時。

關于安裝環境的限制

有些庫并不是在所有的 Python 版本中都適用的,若一個庫安裝在一個未兼容的 Python 環境中,理論上不應該在使用時才報錯,而應該在安裝過程就使其失敗,提示禁止安裝。

這樣的功能,可以使用 python_requires 來實現。

setup(...python_requires='>=2.7, <=3',
)

生成可執行文件的分發

from setuptools import setup, find_packagessetup(name="mytest",version="1.0",author="wangbm",author_email="wongbingming@163.com",description="Learn to Pack Python Module",url="http://iswbm.com/", packages=find_packages(),# 用來支持自動生成腳本,安裝后會自動生成 /usr/bin/foo 的可執行文件# 該文件入口指向 foo/main.py 的main 函數entry_points={'console_scripts': ['foo = foo.main:main']},# 將 bin/foo.sh 和 bar.py 腳本,生成到系統 PATH中# 執行 python setup.py install 后# 會生成 如 /usr/bin/foo.sh 和 如 /usr/bin/bar.pyscripts=['bin/foo.sh', 'bar.py']
)

上面的 scripts 里有的腳本中有 shpy 后綴,那么安裝后,setuptools 會原封不動的移動到 /usr/bin 中,并添加可執行權限。

若你想對這些文件再作一些更改,比如去掉多余的后綴,可以這樣做

from setuptools.command.install_scripts import install_scriptsclass InstallScripts(install_scripts):def run(self):setuptools.command.install_scripts.install_scripts.run(self)# Rename some script filesfor script in self.get_outputs():if basename.endswith(".py") or basename.endswith(".sh"):dest = script[:-3]else:continueprint("moving %s to %s" % (script, dest))shutil.move(script, dest)setup(...scripts=['bin/foo.sh', 'bar.py'],cmdclass={"install_scripts": InstallScripts}
)

ext_modules

ext_modules 參數用于構建 C 和 C++ 擴展擴展包。其是 Extension 實例的列表,每一個 Extension 實例描述了一個獨立的擴展模塊,擴展模塊可以設置擴展包名,頭文件、源文件、鏈接庫及其路徑、宏定義和編輯參數等。如:

setup(# other arguments here...ext_modules=[Extension('foo',glob(path.join(here, 'src', '*.c')),libraries = [ 'rt' ],include_dirs=[numpy.get_include()])]
)

詳細了解可參考:https://docs.python.org/3.6/distutils/setupscript.html#preprocessor-options

指定release

setup.py 里只能指定 version,而不能指定 release,如果你需要變更版本號,可以使用 --release 參數進行指定

python setup.py bdist_rpm --release=20200617

8. 打包輔助神器PBR 是什么?

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

pbr 會讀取和過濾setup.cfg中的數據,然后將解析后的數據提供給 setup.py 作為參數。包含如下功能:

  1. 從git中獲取Version、AUTHORS and ChangeLog信息
  2. Sphinx Autodoc。pbr 會掃描project,找到所有模塊,生成stub files
  3. Requirements。pbr會讀取requirements.txt,生成setup函數需要的install_requires/tests_require/dependency_links

這里需要注意,在 requirements.txt 文件的頭部可以使用:--index https://pypi.python.org/simple/,這一行把一個抽象的依賴聲明如 requests==1.2.0 轉變為一個具體的依賴聲明 requests 1.2.0 from pypi.python.org/simple/

  1. long_description。從README.rst, README.txt or README file中生成long_description參數

使用pbr很簡單:

from setuptools import setupsetup(setup_requires=['pbr'],pbr=True,
)

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

[files]
data_files =etc/pbr = etc/pbr/*etc/neutron =etc/api-paste.inietc/dhcp-agent.inietc/init.d = neutron.init

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

到此,我講了三種編寫使用 setup.py 的方法

  • 使用命令行參數指定,一個一個將參數傳遞進去(極不推薦)
  • 在 setup.py 中的setup函數中指定(推薦使用)
  • 使用 pbr ,在 setup.cfg 中指定(易于管理,更推薦)

9. 如何使用 setup.py 構建包

0、查看setup.py工具的幫助信息

python setup.py --help-commands
Standard commands:build             build everything needed to installbuild_py          "build" pure Python modules (copy to build directory)build_ext         build C/C++ extensions (compile/link to build directory)build_clib        build C/C++ libraries used by Python extensionsbuild_scripts     "build" scripts (copy and fixup #! line)clean             clean up temporary files from 'build' commandinstall           install everything from build directoryinstall_lib       install all Python modules (extensions and pure Python)install_headers   install C/C++ header filesinstall_scripts   install scripts (Python or otherwise)install_data      install data filessdist             create a source distribution (tarball, zip file, etc.)register          register the distribution with the Python package indexbdist             create a built (binary) distributionbdist_dumb        create a "dumb" built distributionbdist_rpm         create an RPM distributionbdist_wininst     create an executable installer for MS Windowscheck             perform some checks on the packageupload            upload binary package to PyPIExtra commands:bdist_wheel       create a wheel distributionalias             define a shortcut to invoke one or more commandsbdist_egg         create an "egg" distributiondevelop           install package in 'development mode'dist_info         create a .dist-info directoryeasy_install      Find/get/install Python packagesegg_info          create a distribution's .egg-info directoryinstall_egg_info  Install an .egg-info directory for the packagerotate            delete older distributions, keeping N newest filessaveopts          save supplied options to setup.cfg or other config filesetopt            set an option in setup.cfg or another config filetest              run unit tests after in-place build (deprecated)upload_docs       Upload documentation to sites other than PyPi such as devpiptr               run unit tests after in-place build (deprecated)pytest            run unit tests after in-place build (deprecated)isort             Run isort on modules registered in setuptoolsflake8            Run Flake8 on modules registered in setup.pyusage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]or: setup.py --help [cmd1 cmd2 ...]or: setup.py --help-commandsor: setup.py cmd --help

1、構建源碼發布包。

用于發布一個 Python 模塊或項目,將源碼打包成 tar.gz (用于 Linux 環境中)或者 zip 壓縮包(用于 Windows 環境中)

$ python setup.py sdist

那這種包如何安裝呢,答案是,使用 easy_install 工具。

$ easy_install xxx.tar.gz

使用 sdist 將根據當前平臺創建默認格式的存檔。在類 Unix 平臺上,將創建后綴后為 .tar.gz 的 gzip 壓縮的tar文件分發包,而在Windows上為 ZIP 文件。

當然,你也可以通過指定你要的發布包格式來打破這個默認行為

$ python setup.py sdist --formats=gztar,zip

你可以指定的格式有哪些呢?

創建一個壓縮的tarball和一個zip文件。可用格式為:

格式描述
zip壓縮檔
gztargzip 壓縮的tar 文件
bztarbzip2格式的tar 文件
xztarxz 的tar 文件
ztar壓縮的tar文件
tartar文件

對以上的格式,有幾點需要注意一下:

  • 在版本3.5中才添加了對 xztar 格式的支持
  • zip 格式需要你事先已安裝相應的模塊:zip程序或zipfile模塊(已成為Python的標準庫)
  • ztar 格式正在棄用,請盡量不要使用

另外,如果您希望歸檔文件的所有文件歸root擁有,可以這樣指定

python setup.py sdist --owner=root --group=root

2、構建二進制分發包。

在windows中我們習慣了雙擊 exe 進行軟件的安裝,Python 模塊的安裝也同樣支持 打包成 exe 這樣的二進制軟件包。

$ python setup.py bdist_wininst  # 創建"*.exe"的文件
$ python setup.py bdist_msi  # 創建"*.msi"的文件
$ python setup.py bdist --format=msi  # 同樣是創建"*.msi"的文件

而在 Linux 中,大家也習慣了使用 rpm 來安裝包,對此你可以使用這條命令實現 rpm 包的構建

$ python setup.py bdist_rpm

若你喜歡使用 easy_install 或者 pip 來安裝離線包。你可以將其打包成 egg 包

$ python setup.py bdist_egg

若你的項目,需要安裝多個平臺下,既有 Windows 也有 Linux,按照上面的方法,多種格式我們要執行多次命令,為了方便,你可以一步到位,執行如下這條命令,即可生成多個格式的進制

$ python setup.py bdist

3、打包whl和egg格式

修改"setup.py"文件

# from distutils.core import setup
from setuptools import setup  # 注意哈,setuptools是基于distutils進行封裝的,但打wheel包時要從setuptools包導入setup模塊喲~setup(# 指定項目名稱,我們在后期打包時,這就是打包的包名稱,當然打包時的名稱可能還會包含下面的版本號喲~name='devops',# 指定版本號version='0.1.1',# 這是對當前項目的一個描述description='Python automatic operation and maintenance platform',# 作者是誰,指的是此項目開發的人,這里就寫你自己的名字即可author='yinzhengjie',# 作者的郵箱author_email='y1053419035@qq.com',# 寫上項目的地址,比如你開源的地址開源寫博客地址,也開源寫GitHub地址,自定義的官網地址等等。url='https://www.cnblogs.com/yinzhengjie/p/14124623.html',# 指定包名,即你需要打包的包名稱,要實際在你本地存在喲,它會將指定包名下的所有"*.py"文件進行打包喲,但不會遞歸去拷貝所有的子包內容。# 綜上所述,我們如果想要把一個包的所有"*.py"文件進行打包,應該在packages列表寫下所有包的層級關系喲~這樣就開源將指定包路徑的所有".py"文件進行打包!packages=['devops', "devops.dev", "devops.ops"],
)

運行命令

pip install wheel
python setup.py bdist_egg  # 打"*.egg"的包
python setup.py bdist_wheel  # 打"*.whl"的包

10. 如何使用 setup.py 安裝包

正常情況下,我們都是通過以上構建的源碼包或者二進制包進行模塊的安裝。

但在編寫 setup.py 的過程中,可能不能一步到位,需要多次調試,這時候如何測試自己寫的 setup.py 文件是可用的呢?

這時候你可以使用這條命令,它會將你的模塊安裝至系統全局環境中

$ python setup.py install

如若你的項目還處于開發階段,頻繁的安裝模塊,也是一個麻煩事。

這時候你可以使用這條命令安裝,該方法不會真正的安裝包,而是在系統環境中創建一個軟鏈接指向包實際所在目錄。這邊在修改包之后不用再安裝就能生效,便于調試。

$ python setup.py develop

11. 如何發布包到 PyPi?

通過上面的學習,你一定已經學會了如何打包自己的項目,若你覺得自己開發的模塊非常不錯,想要 share 給其他人使用,你可以將其上傳到 PyPi (Python Package Index)上,它是 Python 官方維護的第三方包倉庫,用于統一存儲和管理開發者發布的 Python 包。

如果要發布自己的包,需要先到 pypi 上注冊賬號。然后創建 ~/.pypirc 文件,此文件中配置 PyPI 訪問地址和賬號。如的.pypirc文件內容請根據自己的賬號來修改。

典型的 .pypirc 文件

[distutils]
index-servers = pypi[pypi]
username:xxx
password:xxx

然后使用這條命令進行信息注冊,完成后,你可以在 PyPi 上看到項目信息。

$ python setup.py register

注冊完了后,你還要上傳源碼包,別人才使用下載安裝

$ python setup.py upload

或者也可以使用 twine 工具注冊上傳,它是一個專門用于與 pypi 進行交互的工具,詳情可以參考官網:https://www.ctolib.com/twine.html,這里不詳細講了。

參考文章

  • http://blog.konghy.cn/2018/04/29/setup-dot-py/
  • https://note.qidong.name/2018/01/python-setup-requires/
  • https://blog.konghy.cn/2018/04/29/setup-dot-py/
  • https://zhuanlan.zhihu.com/p/276461821?utm_oi=948852089393336320

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453731.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453731.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453731.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

周進度----06

周學習進度06 周學習進度06 第16周 所花時間&#xff1a; 60min60min100min100min100min100min90min60min60min 代碼量&#xff08;行&#xff09; 500-800 博客量&#xff08;篇&#xff09; 4 了解到的知識 css樣式表的一些知識 項目流程的初步了解 一周的學習心得…

八個實用的CMD命令及開始→運行→命令集錦

這篇文章是很久前收藏在自己筆記本內的,具體的來源地址不清楚,先謝一下原作者吧. 共享出來大家一起學習一下: 一&#xff0c;ping    它是用來檢查網絡是否通暢或者網絡連接速度的命令。作為一個生活在網絡上的管理員或者黑客來說&#xff0c;ping命令是第一個必須掌握的DO…

2019如何轉換2010_9102年,你還不知道PPT怎么轉換成視頻嗎?小心落伍了

你在刷抖音的時候有沒有刷過這類視頻&#xff1a;成為人生贏家必備的書單、5個讓你看透人性的電影、6個讓你升職加薪的APP...如果你細心觀察的話&#xff0c;會發現這類視頻的做法基本都是一個樣的&#xff0c;像在翻相冊一樣&#xff0c;一頁頁過去&#xff0c;所以它們也叫做…

深度學習之RetinaNet

總述 Focal loss主要是為了解決one-stage目標檢測中正負樣本比例嚴重失衡的問題。該損失函數降低了大量簡單負樣本在訓練中所占的權重&#xff0c;也可理解為一種困難樣本挖掘。 目標識別有兩大經典結構: 第一類是以Faster RCNN為代表的兩級識別方法&#xff0c;這種結構的第…

js生成圖片

var image new Image(); var c document.getElementById("myCanvas"); var ctx c.getContext("2d"); var img document.getElementById("scream"); ctx.font "10px Arial";function createImg(name, zuowei, color) {// 姓名ctx…

淺談如何學習linux

一.為什么要學linux? 當然最重要是愛好和興趣&#xff01;如果你這種必要學&#xff0c;或者根本不喜歡&#xff0c;請不要浪費時間&#xff0c;你學也學不好&#xff01; 二.起步 你應該為自己創造一個學習linux的環境--在電腦上裝一個linux或unix 問題1&#xff1a;版本…

python的datetime函數_Python連載8-datetime包函數介紹

一、datetime包(上接連載7內容)1.函數&#xff1a;datetime(1)用法&#xff1a;輸入一個日期&#xff0c;來返回一個datetime類?(2)格式&#xff1a;datetime.datetime(年&#xff0c;月&#xff0c;日&#xff0c;hour&#xff0c;minute&#xff0c;second)其中hour,minute,…

深度學習之 soft-NMS

論文&#xff1a;《Improving Object DetectionWith One Line of Code》soft-NMS 英文論文鏈接&#xff1a;https://arxiv.org/pdf/1704.04503.pdfsoft-NMS github 鏈接&#xff1a;https://github.com/bharatsingh430/soft-nms 絕大部分目標檢測方法&#xff0c;最后都要用到…

項目微管理 - 總結也是新的開始

時間都去哪了&#xff1f;聽著這首耳熟能詳的旋律&#xff0c;感嘆著飛速流逝的年華&#xff0c;我漸漸的陷入到沉思之中。時間過的真的很快&#xff0c;從一名程序員到接手一個一線項目團隊一晃已經2年多了。在這段時間里&#xff0c;我接觸了各種各樣的人&#xff0c;處理了各…

一維二維_Excel二維數據轉一維,2種方法輕松搞定

今天是2020年1月1日&#xff0c;祝各位小伙伴們新年快樂&#xff0c;開心每一天~如下所示&#xff0c;左邊是二維交叉數據表&#xff0c;我們希望快速轉換成右邊的一維數據表如果復制粘貼&#xff0c;效率太低了&#xff0c;今天分享兩種方法&#xff0c;實現快速轉換1、powerq…

數百種 Windows 軟件的免費替代品列表

程序所執行任務的描述WindowsLinux1) 網絡連接網頁瀏覽器微軟 IE&#xff0c;網景 Netscape / Mozilla&#xff0c; Opera [私有]&#xff0c;Firebird&#xff0c;……1) Netscape/Mozilla 2) Galeon. 3) Konqueror. 4) Opera.[私有] 5) Firebird. 6) Nautilus 7) Epiphany 8)…

深度學習之 Cascade R-CNN

Zhaowei Cai, Nuno Vasconcelos. 《Cascade R-CNN: Delving into High Quality Object Detection》. CVPR 2018.論文鏈接&#xff1a;https://arxiv.org/abs/1712.00726代碼鏈接&#xff1a;https://github.com/zhaoweicai/cascade-rcnn 前言 IOU閾值被用來定義正負例&#x…

轉換文檔參數_明明2秒可以搞定Word、Excel相互轉換,你卻用了半小時!真虧了...

我們在用office三件套工作的時候&#xff0c;經常都需要對文件的格式進行轉換&#xff0c;像是Word文檔和Excel表格的轉換&#xff0c;很多小伙伴都要花上半個小時甚至以上的時間才能搞定&#xff0c;效率實在不行。別擔心&#xff0c;今天小編將分享能快速完成Word、Excel轉換…

深度學習之 DCN(Deformable Convolution)-可變形卷積

Paper link: http://openaccess.thecvf.com/content_ICCV_2017/papers/Dai_Deformable_Convolutional_Networks_ICCV_2017_paper.pdfhttps://arxiv.org/pdf/1703.06211 Code link: https://github.com/msracver/Deformable-ConvNets Abstract 如何有效地對幾何圖形的變化進行…

軟件開發 項目進展 軟件架構 指南

軟件開發&#xff0c;標準化流水線式開發的實施構想 軟件開發&#xff0c;標準化流水線式開發的實施構想 近日看到一篇博文&#xff0c;討論標準化流水線開發模式的話題&#xff0c;但是這篇博文僅僅提出這個問題&#xff0c;未見回應。 這其實是一個很大的問題&#xff0c;我…

linux 下php多版本安裝

php-multi-version ubuntu apt-get 安裝php5.6 添加軟件源sudo add-apt-repository ppa:ondrej/php sudo apt-get updatesudo apt-get install php5.6sudo apt-get install php5sudo apt-get install php7 /usr/local/bin 與/usr/bin echo $PATH/usr/local/sbin:/usr/local/bin…

c++ 舞伴配對問題_挑戰新物體描述問題,視覺詞表解決方案超越人類表現

編者按&#xff1a;最近&#xff0c;研究者們發布了 nocaps 挑戰&#xff0c;用以測量在沒有對應的訓練數據的情況下&#xff0c;模型能否準確描述測試圖像中新出現的各種類別的物體。針對挑戰中的問題&#xff0c;微軟 Azure 認知服務團隊和微軟研究院的研究員提出了全新解決方…

深度學習之雙線性插值(Bilinear interpolation)

1. 什么是插值 Interpolation is a method of constructing new data points within the range of a discrete set of known data points. Image interpolation refers to the“guess”of intensity values at missing locations. 圖片放大是圖像處理中的一個特別基礎的操作。…

div table 超出了_div包裹的table,table的寬度超出了的寬度,出現的滾動條的在windows下無法拖動...

1.父級div是否設置了寬度&#xff0c;只有設置了寬度且滾動條在div內才是你想要控制的滾動2.僅憑你說的這些屬性不知道滾動條怎么不能動&#xff0c;可以貼一下代碼&#xff1f;3.橫向需要滾動條的話必須設置table的確定寬度做了一個demo:.table{table-layout:fixed; width:…

第二階段站立會議7

昨天&#xff1a;美化頁面 今天&#xff1a;進行項目上傳 問題&#xff1a;阿里云服務器上的mysql出現連接問題轉載于:https://www.cnblogs.com/sdysyhj/p/8301489.html