将单个 python 文件与"extras"包打包



我目前有一个名为"peewee"的项目,它由一个python文件组成,peewee.py。 还有一个包含单元测试的模块"tests.py"。 这很棒,想要使用该库的人只需获取单个文件并使用它即可运行。

我最近想添加一些额外的内容,但不确定如何做到这一点以使命名空间正确。 如果你看一下我的项目的根目录,它是这样的:

peewee.py
tests.py

我想添加以下内容:

extras/__init__.py
extras/foo.py
extras/bar.py

这是棘手的部分。 我希望它使使用单个文件的人仍然可以这样做,但是如果您想要额外的功能,您也可以拥有它们。 我希望额外的内容被命名为:

from peewee.extras import foo
from peewee.extras.bar import Baz

我的 setup.py 看起来有点像这样:

setup(
    name='peewee',
    packages=['extras'],
    py_modules=['peewee'],
    # ... etc ...
)

但这并不完全有效。 任何帮助将不胜感激!

设置包

正如@ThomasK所说,最简单的方法是使用包。 如果将包命名为 peewee ,则可以编辑顶级__init__.py文件,以允许用户继续以与以前相同的方式使用您的包。

首先,包和子文件夹的目录结构:

peewee/
    __init__.py
    peewee.py
    extras/
        __init__.py
        foo.py
        bar.py

__init__.py文件

接下来,您需要在顶级__init__.py中添加几行。

你可以选择一种快速而肮脏的方法,只包括:

from peewee.peewee import *

这会将所有内容放在包的顶级命名空间中peewee.py。 或者,您可以采用更传统的替代方法,仅显式导入那些应该位于顶层的方法。

from peewee.peewee import funtion1, class1,...

而且,为了向后兼容,您可以显式设置模块的 __all__ 属性以仅包含 peewee

__all__ = ['peewee']

这将让人们在真正需要的情况下继续使用from peewee import *

写入setup.py文件

最后,您还必须设置一些安装脚本等。 Zed Shaw的学习Python The Hard Way练习46有一个简单明了的项目框架,你应该使用。

最重要的部分是setup.py文件。示例页面不太长,Zed为制作一本真正伟大的书付出了很多努力,所以我不会在这里重新发布(尽管整本书都是免费提供的)。您还可以阅读更长的说明/文档,以便为distutils编写 setup.py 文件,但是LPTHW将为您提供一些可以快速轻松地完成您想要的所有事情的功能。

总包目录结构

请注意,您的最终目录结构实际上会大一些(peewee-pkg的名称无关紧要,bin是可选的 - 子文件夹的名称很重要)

peewee-pkg/
    setup.py
    bin
    peewee/
        __init__.py
        peewee.py
        extras/
            __init__.py
            foo.py
            bar.py

安装和使用

之后,如果您愿意,实际上可以将包发布到 PyPi,也可以直接将其分发给用户。 他们需要做的就是运行:

 python setup.py install

一切都将可供他们使用。

导入安装后

最后,如果您如前所述在peewee/__init__.py文件中执行特定导入,您的用户仍然可以执行以下操作:

from peewee import function1, class1, ...

但是现在他们也可以使用import peewee.extras来获取附加功能(或import peewee.extras.foo as foofrom pewee.extras.foo import extra_awesome)等。而且,正如您在问题中提出的,他们还将能够做到:

from pewee.extras import foo

然后访问 foo 的函数,就好像文件在当前目录中一样。

开发包的有用说明

在计算机上,您应该运行:

python setup.py develop

这将把包安装到你的路径上,就像使用python setup.py install一样;但是,develop告诉python每次使用该模块时重新检查文件,以便每次你进行更改时,它们将立即可供系统进行测试。