查看已安装docker_应用程序

对于任何Python开发人员而言,了解如何使用软件包都是一项重要技能。 但是,与语言本身不同,Python打包没有禅宗。

打包是Python中最难学的东西之一。 这就是为什么我们要求两名强大的复仇者帮助我们。

我们将在一个小型应用程序上与Clint和Natasha一起工作,从几个模块开始,最后完成我们自己的python包。

可以在这里找到本文中的代码示例。

模组

我们将代码分为模块以实现模块化。 python模块只是一个包含代码的文件。 模块化代码更易于使用。 为什么?

减少了在编码时要保留在(人类)内存中的内容,减少了滚动,减少了当您必须查找特定内容时确切知道要查找的位置,将大问题分解为更小的问题,等等。

让我们见见克林特。 Clint正在开发一个新应用,该应用将根据输入的命令行参数打印一条消息。 该应用程序使用自定义打印功能。 Clint要求Natasha为他编写该代码。 Natasha为Clint创建bprint模块,然后将其导入到他的app模块中。

"""01/app.py
Main app module."""


import sys

import bprint

commands = {"reboot": "Rebooting launch control system.",
            "halt": "Halting all systems.",
            }

try:
    command = sys.argv[1]
except IndexError:
    bprint.upper_print("No command provided. Terminating.")
    sys.exit(1)
else:
    print(commands.get(command, "Doing absolutely nothing."))

这是bprint模块。

"""01/bprint.py
Cool print functions."""


def upper_print(message):
    print(message.upper())


if __name__ == '__main__':
    print("Hello little child.")
    upper_print("You have run bprint as a script.")
    print("That seems great. Goodnight.")

让我们看看Clint的目录结构。

.
├── app.py
└── bprint.py

0 directories, 2 files

Clint可以使用以下方式运行他的应用程序:

python3 app.py <command>

太棒了! 模块非常有用。 克林特和娜塔莎在一起做得很好。 似乎他们还不需要任何软件包。

配套

在他的应用程序的下一版本中,Clint决定他需要更多的自定义打印功能来显示其消息。 他再次要求娜塔莎(Natasha)帮助他。 Natasha编写了一个模块sprint其中包含Clint所需的代码。

Clint可以将文件及其app.py复制到同一目录中并使用它们。

.
├── app.py
├── bprint.py
└── sprint.py

0 directories, 3 files

但是现在Clint感到不安,他的代码与Natasha的代码混在一起了。 随着代码库大小的增加,这将导致问题。 他决定重新组织它。 因此,他将Natasha的代码移到了一个子文件夹中,并修改了app.py文件中的app.py内容。

.
├── app.py
└── print_helpers
 ├── bprint.py
 └── sprint.py

1 directory, 3 files

Clint的修改后的app.py文件。

"""02/app.py
Clint's new main app module."""


import sys

from print_helpers import bprint, sprint

commands = {"reboot": "Rebooting launch control system.",
            "halt": "Halting all systems.",
            }

try:
    command = sys.argv[1]
except IndexError:
    bprint.upper_print("No command provided. Terminating.")
    sys.exit(1)
else:
    sprint.tacky_print(commands.get(command, "Doing absolutely nothing."))

就是这样。 任何想要使用Natasha代码的人都可以(在她的允许下)将print_helpers目录复制到他们的代码中并import 。

Clint刚刚创建了Natasha的代码包。 python软件包是模块的集合。 开发人员通常将彼此相关的模块放在同一包中。

分配

娜塔莎对此不满意。 复制粘贴完整的软件包很容易出错。 感觉就像是临时的hack。 Natasha尝试了解有关软件包的更多信息,并发现通过多做一些工作,她可以以更好的方式分发代码。

通过提供setup.py安装脚本。

setup.py文件中可以包含很多内容。 这是娜塔莎(Natasha)使用的最小示例。

"""03/setup.py
Natasha's initial setup.py"""

from setuptools import setup, find_packages


setup(
        name='print-helpers',
        version='0.1',
        packages=find_packages(),
    )

Natasha还在print_helpers目录中创建了一个名为__init__.py的空文件。 这是python必需的。 包含__init__.py的目录被标识为包。

.
├── print_helpers
│   ├── bprint.py
│   ├── __init__.py
│   └── sprint.py
└── setup.py

1 directory, 4 files

Natasha现在可以将所有代码打包到一个存档文件中并进行分发。 推荐使用Wheels分发软件包。 娜塔莎(Natasha)可以通过运行来为其包装创建轮子

python3 setup.py bdist_wheel

这将与dist /目录中的wheel一起生成许多新文件。

.
├── build
│   ├── bdist.linux-x86_64
│   └── lib
│       └── print_helpers
│           ├── bprint.py
│           ├── __init__.py
│           └── sprint.py
├── dist
│   └── print_helpers-0.1-py3-none-any.whl
├── print_helpers
│   ├── bprint.py
│   ├── __init__.py
│   └── sprint.py
├── print_helpers.egg-info
│   ├── dependency_links.txt
│   ├── PKG-INFO
│   ├── SOURCES.txt
│   └── top_level.txt
└── setup.py

7 directories, 12 files

Natasha然后可以将该.whl文件发送给Clint。

使用包

Clint现在可以使用pip安装Natasha的软件包。 Pip是用于管理python软件包的命令行实用程序。 这是Clint运行的命令。

pip install ./print_helpers-0.1-py3-none-any.whl

安装套件

pip将自动将Natasha的代码文件从软件包复制到Clint计算机上的特定位置。 这些是Python在代码中遇到import语句时查找模块的位置。

检查pip show的输出以检查新安装的软件包的位置。

$ pip show print-helpers

Name: print-helpers
Version: 0.1
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Location: /home/ramit/my_py_env/lib/python3.6/site-packages
Requires: 
Required-by:

一台计算机到另一台计算机的位置不同,但是您也可以在sys.path找到此位置,它是python搜索模块的目录列表。

导入包裹

现在,在Clint的计算机上运行的所有Python代码都可以导入Natasha的软件包。 Clint不需要在项目中维护Natasha的代码及其副本。

"""04/app.py"""


import sys

from print_helpers import bprint, sprint

commands = {"reboot": "Rebooting launch control system.",
            "halt": "Halting all systems.",
            }

try:
    command = sys.argv[1]
except IndexError:
    bprint.upper_print("No command provided. Terminating.")
    sys.exit(1)
else:
    sprint.tacky_print(commands.get(command, "Doing absolutely nothing."))

Clint应用程序的目录结构。

.
└── app.py

0 directories, 1 file

包装可以做更多

聚酰亚胺

Pip可以从PyPI,本地或远程存档,Github存储库或项目目录中安装软件包。 通常将Python软件包上传到PyPI ,后者是python软件包的存储库。 Natasha可以将其软件包上传到PyPI,并且任何想要使用其软件包的人都可以使用pip直接安装该软件包,从而无需手动获取软件包存档。 这就是我们大多数人所熟悉的。

多余的文件

尝试在Github上找到一些python软件包。 如果您不记得任何一个,这里就是一个 。 这是另一个 。 检查上面链接的存储库的目录结构。

.
├── LICENSE.txt
├── MANIFEST.in
├── README.md
├── requirements.txt
├── setup.py
├── src
│   └── fsanitize
│       ├── app.py
│       ├── __init__.py
│       ├── logmgr.py
│       └── sanitize.py
└── tests
    ├── __init__.py
    └── test_all.py

3 directories, 11 files

这些文件包含许多文件以及setup.py 。 这些可以包括测试,测试配置,清单文件,许可证信息,文档,构建脚本等等。 这些与软件包内的python模块一起分发。

应用程序包

理想情况下,Clint还将为其应用程序创建一个程序包,并将Natasha的程序包指定为依赖项。 依赖关系会与主软件包一起自动安装。