Python包管理

目录

pip模块管理工具

虚拟环境

Pypi模块发布

创建模块工程:

setup() 参数

name

version

packages

description

url

author

license

classifiers

keywords

project_urls

install_requires

python_requires

package_data

data_files

其他初始化文件

setuptools 默认打包的文件

PyPI 上传推荐配置

一个完整的 setup.py 示例

使用安装文件创建发布包

模块打Wheel

安装 Wheel

上传模块



pip模块管理工具

在安装了Python环境的时候自己会安装一个pip工具,所以用户在命令行下直接可以执行pip命令

升级pip工具:

如果pip工具有新版本发布时,使用pip命令就会提示更新,因此可以使用以下命令更新

 python3  -m pip install --upgrade pip

查询模块:

pip3 search pymsql

安装模块:

pip3 install pymysql

下载模块到本地:

pip3 download  pymysql

列出已安装的模块:

pip3 list

查看过期版本的模块:

pip3 list --outdate

更新指定模块:

pip3 install --upgrade setuptools

卸载模块

pip3 uninstall PyMySQL -y

虚拟环境

如果我们要同时开发多个应用程序,那这些应用程序都会共用一个Python,就是安装在系统的Python 3。如果应用A需要jinja 2.7,而应用B需要jinja 2.6怎么办?

这种情况下,每个应用可能需要各自拥有一套“独立”的Python运行环境。virtualenv就是用来为一个应用创建一套“隔离”的Python运行环境。

安装virtualevn工具:

pip3 install virtualenv

创建虚拟环境:

mkdir myproject
cd myproject
virtualenv --no-site-packages venv 

注意:使用virtualenv --version,看到自己的版本大于20,就可以将如下这段删除:

export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'

因为从版本20开始,默认就是’--no-site-packages‘了。

激活虚拟环境:

source venv/bin/activate

意到命令提示符变了,有个(venv)前缀,表示当前环境是一个名为venv的Python环境。在venv环境下,用pip安装的包都被安装到venv这个环境下,系统Python环境不受任何影响。也就是说,venv环境是专门针对myproject这个应用创建的

 

virtualenv原理:

virtualenv是如何创建“独立”的Python运行环境的呢?原理很简单,就是把系统Python复制一份到virtualenv的环境,用命令source venv/bin/activate进入一个virtualenv环境时,virtualenv会修改相关环境变量,让命令pythonpip均指向当前的virtualenv环境。

退出虚拟环境

deactivate

Pypi模块发布

Python为了方便管理和使用开源项目,建立了一个第三方的仓库:Pypi(Python Package Index,https://pypi.org/),所有开发者都可以在该网站进行注册后,通过工具在Pypi上发布自己的模块

 

创建模块工程:

在目录 firstApp 下新建安装文件 setup.py,然后创建包 myapp 模拟要打包源码包:

firstApp
    ├── myapp
    │     └── __init__.py
    └── setup.py

一个最简单的 setup.py 文件内容如下:

from setuptools import setup

setup(
    name='firstApp', # 应用名
    version='0.0.1', # 版本号
    packages=['myapp'], # 包括在安装包内的 Python 包
)

以上就是 Python 打包和分发的全部内容,当然是最简单的功能。更复杂的打包,比如模块过滤,非 py 文件打包,作者信息等常见的需求,都被实现在 setup() 内。所以接下来详细介绍 setup()。


setup() 参数

这里写图片描述

这里写图片描述

上面的 setup.py 安装文件内,我们已经使用了 setup() 一些参数:name, version, packages。

name

项目名,也是最终在 PyPI 上搜索的名称。

name = 'firstApp'

 

version

项目版本号,一般由三部分组成:MAJOR, MINOR, MAINTENANCE。
- MAJOR version when they make incompatible API changes,
- MINOR version when they add functionality in a backwards-compatible manner, and
- MAINTENANCE version when they make backwards-compatible bug fixes.

版本号的选择参见:https://packaging.python.org/tutorials/distributing-packages/#choosing-a-versioning-scheme

version='0.0.1'

packages

列出项目内需要被打包的所有 package。一般使用 setuptools.find_packages() 自动发现。

packages=find_packages(exclude=['contrib', 'docs', 'tests*'])

exclude 用于排除不打包的 package。

description

项目的简短描述,一般一句话就好,会显示在 PyPI 上名字下端。

description='My first Python project'

对项目的完整描述,使用 long_description。如果此字符串是 rst 格式的,PyPI 会自动渲染成 HTML 显示。也可指定使用 markdown。

long_description=long_description,
long_description_content_type='text/x-rst'

url

通常为 GitHub上 的链接或者 readthedocs 的链接。。

url='https://github.com/pypa/sampleproject'

author

作者信息。

author='example',
author_email='[email protected]'

license

项目许可证。

license='MIT'

关于各种许可证的介绍和选择,参考:https://choosealicense.com/。

classifiers

项目分类,完整可选项参考:https://pypi.python.org/pypi?%3Aaction=list_classifiers。

classifiers=[
    # How mature is this project? Common values are
    # 3 - Alpha
    # 4 - Beta
    # 5 - Production/Stable
    'Development Status :: 3 - Alpha',

    # Indicate who your project is intended for
    'Intended Audience :: Developers',
    'Topic :: Software Development :: Build Tools',

    # Pick your license as you wish (should match "license" above)
     'License :: OSI Approved :: MIT License',

    # Specify the Python versions you support here. In particular, ensure
    # that you indicate whether you support Python 2, Python 3 or both.
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.6',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.2',
    'Programming Language :: Python :: 3.3',
    'Programming Language :: Python :: 3.4',
],

keywords

项目关键词列表。

keywords='sample setuptools development'

project_urls

项目相关额外连接,如代码仓库,文档地址等。

project_urls={
    'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/',
    'Funding': 'https://donate.pypi.org',
    'Say Thanks!': 'http://saythanks.io/to/example',
    'Source': 'https://github.com/pypa/sampleproject/',
    'Tracker': 'https://github.com/pypa/sampleproject/issues',
}

install_requires

项目依赖的 Python 库,使用 pip 安装本项目时会自动检查和安装依赖。

install_requires=['pyyaml']

依赖的安装参考:https://packaging.python.org/discussions/install-requires-vs-requirements/#install-requires-vs-requirements-files。

python_requires

指定项目依赖的 Python 版本。

python_requires='>=3'

package_data

项目依赖数据文件,数据文件必须放在项目目录内且使用相对路径。

package_data={
    'myapp': ['data/*.yml'],
}

如果不指定作为目录的键为空串,则代表对所有模块操作(下例中将包含所有包内 data 目录下的 yaml 文件):

package_data={
    '': ['data/*.yml'],
}

data_files

如果数据文件存在于项目外,则可以使用 data_files 参数或者 MANIFEST.in 文件进行管理。

  • 如果用于源码包,则使用 MANIFEST.in;
  • 如果用于 wheel,则使用 data_files。

    data_files=[(‘mydata’, [‘data/conf.yml’])]

上述设置将在打包 wheel 时,将 data/conf.yml 文件添加至 mydata 目录。

data_files 不能使用路径通配符。

此外,scripts, py_modeles, entry_points, console_scripts 等参数参考:https://packaging.python.org/tutorials/distributing-packages/#setup-args。


其他初始化文件

在阅读 Github 上的 Python 库时,除了最基本核心的 setup.py 文件和主程序之外,还会看到其他一些文件。本节将介绍它们的作用和使用方法。

setup.cfg

包含了构建时候的一些默认参数,如:

[bdist_wheel]

universal=1

用于在使用 bdist_wheel 的时候的默认设置 --universal 参数 。

README.rst/README.md

项目说明文档,使用 reStrutruedText 可以在 PyPI 上很好的渲染,但 Markdown 则支持不够好。

MANIFEST.in

此文件在打源码包的时候告诉 setuptools 还需要额外打包哪些文件。

# Include the README
include *.md

# Include the license file
include LICENSE.txt

# Include the data files
recursive-include data *

不同于 data_files,MANIFEST.in 支持路径通配符。

LICENSE.txt

项目许可说明文件。


setuptools 默认打包的文件

  • README.rst/README.md
  • setup.cfg
  • MANIFEST.in

所以其他的文件,如 LICENSE.txt,在源码包时需要手动在 MANIFEST.in 里添加 include,在 wheel 包时需要在 setup.cfg 添加:

[metadata]
license_file = LICENSE.txt

 

PyPI 上传推荐配置

  • setup.py
    • name
    • version
    • author
    • author_email
    • url
    • packages
    • description
    • package_data/data_files
  • setup.cfg
  • MANIFEST.in
  • README.rst
  • LICENSE.txt
  • <项目>

一个完整的 setup.py 示例

from setuptools import setup, find_packages

with open('README.rst', 'r', encoding='utf-8') as rd:
    long_description = rd.read()

setup(
    name="HelloWorld",
    version="0.1",
    packages=find_packages(),
    scripts=['say_hello.py'],

    # Project uses reStructuredText, so ensure that the docutils get
    # installed or upgraded on the target machine
    install_requires=['docutils>=0.3'],

    package_data={
        # If any package contains *.txt or *.rst files, include them:
        '': ['*.txt', '*.rst'],
        # And include any *.msg files found in the 'hello' package, too:
        'hello': ['*.msg'],
    },

    # metadata for upload to PyPI
    author="Me",
    author_email="[email protected]",
    description="This is an Example Package",
    long_description = long_description,
    license="PSF",
    keywords="hello world example examples",
    url="http://example.com/HelloWorld/", # project home page, if any
    project_urls={
        "Bug Tracker": "https://bugs.example.com/HelloWorld/",
        "Documentation": "https://docs.example.com/HelloWorld/",
        "Source Code": "https://code.example.com/HelloWorld/",
    }

    # could also include long_description, download_url, classifiers, etc.
)

 

使用安装文件创建发布包

有了上面的 setup.py 文件,我们就可以打出各种安装包,主要分为两类:sdist 和 bdist。

Source distribution

使用 sdist 可以打包成 source distribution,支持的压缩格式有:

Format Description Notes
zip zip file (.zip) Windows 默认
gztar gzip’ed tar file (.tar.gz) Unix 默认
bztar bzip2’ed tar file (.tar.bz2)  
xztar xz’ed tar file (.tar.xz)  
ztar compressed tar file (.tar.Z)  
tar tar file (.tar)  

使用方式:

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

现在目录下多出 dist 和 *.egg-info 目录,dist 内保存了我们打好的包,上面命令使用 --formats 指定了打出 .tar.gz 和 .zip 包,如果不指定则如上表根据具体平台默认格式打包。

包的名称为 setup.py 中定义的 nameversion以及指定的包格式,格式如:firstApp-0.0.1.tar.gz。

Built distribution

使用 bdist 可以打出 built distribution,和源码包相比,由于预先构建好,所以安装更快:

Format Description Notes
gztar gzipped tar file (.tar.gz) Unix 默认
bztar bzipped tar file (.tar.bz2)  
xztar xzipped tar file (.tar.xz)  
ztar compressed tar file (.tar.Z)  
tar tar file (.tar)  
zip zip file (.zip) Windows 默认
rpm RPM  
pkgtool Solaris pkgtool  
sdux HP-UX swinstall  
wininst self-extracting ZIP file for Windows  
msi Microsoft Installer.  

使用上,和 sdist 一样,可以使用 --formats 指定包格式。如:

$ python setup.py bdist --formats=rpm

同时为了简化操作,setuptools 提供了如下命令:

Command Formats Notes
bdist_dumb tar, gztar, bztar, xztar, ztar, zip Windows 默认 zip, Unix 默认 gztar
bdist_rpm rpm, srpm  
bdist_wininst wininst  
bdist_msi msi  

所以上面打 rpm 包可以使用:

$ python setup.py bdist_rpm

如果使用 bdist_wininst,打出来的是 exe 安装文件,可以点击安装。

模块打Wheel

Wheel 也是一种 built 包,而且是官方推荐的打包方式。也许你曾经遇见或使用过 egg 包,但现在 wheel 是官方推荐的打包方式(https://wheel.readthedocs.io/en/stable/)。

wheel 包的优点:

  • 快速安装纯Python和本地C扩展包。
  • 避免在安装时任意执行代码。(避免setup . py)
  • 在Windows或macOS上安装C扩展不需要编译器。
  • 为测试和持续集成提供更好的缓存。
  • 创建.pyc文件作为安装的一部分,以确保它们与所使用的Python解释器匹配。
  • 跨平台和机器的安装更加一致。

使用 wheel 打包,首先要安装 wheel:

$ pip install wheel

然后使用 bdist_wheel 打包:

$ python setup.py bdist_wheel

执行成功后,目录下除了 dist 和 *.egg-info 目录外,还有一个 build 目录用于存储打包中间数据。

wheel 包的名称如 firstApp-0.0.1-py3-none-any.whl,其中 py3 指明只支持 Python3。

可以使用参数 --universal,包名如 mfirstApp-0.0.1-py2.py3-none-any.whl,表明 wheel 包同时支持 Python2 和 Python3

使用 universal 也成为通用 wheel 包,反之称为纯 wheel 包。

安装 Wheel

上一节的示例应用没有任何内容。下面添加模块 greet 并重新打包。

# greet.py

def hello():
    print('Hello, welcome to setuptools!')

使用 bdist_wheel 再次打包后,我们可以使用 pip 安装到本地 Python 的 site-packages 目录。

$ pip install dist/fisrtApp-0.0.1-py3-none-any.whl

现在和其他使用 pip 安装的三方库一样使用:

from myapp.greet import hello

hello()

应用开发过程中会频繁变更,每次安装都需要先卸载旧版本很麻烦。使用 develop 开发模式安装的话,实际代码不会拷贝到 site-packages 下,而是除一个指向当前应用的链接(*.egg-link)。这样当前位置的源码改动就会马上反映到 site-packages。使用如下:

$ pip install -e .  # 或者 python setup.py develop

如需卸载,使用 pip uninstall

 

也可以直接使用setup.py,把我们的模块工程直接安装到Python环境中

 python setup.py install 

 

上传模块

安装twine工具:

Python环境默认没有提供模块上传工具,曾经 Python 的分发工具是 distutils,但它无法定义包之间的依赖关系。setuptools 则是它的增强版,能帮助我们更好的创建和分发 Python 包,尤其是具有复杂依赖关系的包。可以安装twine工具完成模块上传

 pip3 install twine

上传模块:

twine update dist/*

配置Pypi认证信息(可选):

在用户家目录($HOME)下创建一个.pypirc文件,

vim $HOME/.pypirc

配置以下信息

[pypi]
username=登录用户名
password=登录密码

 

你可能感兴趣的:(Python方面,python)