如何发布一个Python包

发布流程

如何将一个Python包发布到PyPI呢?官方文档在这里。

打包

  • 方式一:直接使用源码发布

    这种方式发布的包在安装的时候需要临时编译,所以比较慢,但是安装包会比较小

    $ python setup.py sdist
    
  • 方式二:使用轮子(wheels)发布

    这种方式发布的是编译好的包,因此安装会更快

    # 1. 先安装wheel
    $ pip install wheel
    
    # 2.1 如果源码是纯Python而且同时支持2和3,则
    $ python setup.py bdist_wheel --universal
    
    # 2.2 如果只支持特定版本或平台,则使用对应版本执行
    $ python setup.py bdist_wheel
    

准备PyPI账号

首先要有个账号:可以在这里注册。

然后写入~/.pypirc

[distutils]
index-servers=pypi

[pypi]
repository = https://upload.pypi.org/legacy/
username = 
;password = 

上传

推荐使用twine上传。

# 安装twine
$ pip install twine

# 上传打包好的文件
$ twine upload dist/*

scope

不像 NPM 那么强大,PyPI 并不支持 scope,所以给包取名字的时候,我们需要自己考虑命名冲突的问题。

PEP 420 允许给包名指定命名空间(Implicit Namespace Packages)。即使这样,也并没有限定账号,所以其实这个命名空间还是大家都可以用的,只是方便管理。这时,我们可以给自己的包名加上账号前缀作为命名空间,毕竟一般来说,不会有人在自己的包名前面加上别人的账号当前缀吧。

发布有命名空间的包步骤如下:

  1. 包名添加前缀,如 gera2ld-pyserve

    值得注意的是,PEP 503 中提出了包名规范化,会把包名中的特殊字符都替换成 - 再处理,而且在最新的 pip 中,包名中出现其他特殊字符会导致安装失败,所以我们使用 - 来连接前缀。

  2. 文件路径结果增加一层命名空间层,如下:

    ▾ gera2ld/
      # 注:这里不能有 __init__.py
      ▾ pyserve/
          __init__.py
    

    注意命名空间目录下不能有 __init__.py。只有这样,才能多个包共用一个 namespace 互不影响。

  3. 修改 setup.py,手动指定子包的位置:

    setup(
        name='gera2ld-pyserve',
        packages=['gera2ld.pyserve'],
    )
    

    因为 gera2ld 目录下没有 __init__.pysetuptools.find_packages 无法自动找到子包,所以需要手动指定 packages 。

  4. 接下来就可以按上文所述的步骤正常发布和使用了。

你可能感兴趣的:(如何发布一个Python包)