python 包需要适当的目录结构和好的 API 设计指南

Need proper directory structure for python packages and guidelines on good API design

我正在发布一个 python 包,对包装的各个方面都感到困惑。

首先,我的目录结构如下:

SamplePackage/
 - setup.py
 - README.rst
 - LICENSE.rst
 - sampledir/
    -__init__.py
    -sample.py
    -utils.py

目前 __init__setup 无人居住。 sample.py 是包的任何用户想要导入的文件。它包含不同函数形式的api:foo1foo2

utils.py 包含 smaple.py 的辅助小说。后者包含一个语句 import utils

任何放置在sampledir目录下的脚本都可以很容易地import sample并像sample.foo1()一样使用小说。走出这个目录,我可以调用 import sampledir,但不能调用 import sample,这是预期的。所以我需要做 from sampledir import sample。这会导致 sample.py

中的 import utils 行出错
ImportError: No module named 'utils'

在某些地方,我看到同一目录中的文件 import .utils。但是当我尝试这样做时,它会导致语法错误。

为什么我不能从 sampledir 外部导入 sample.py

此外,什么样的目录结构可以让安装了该软件包的用户能够简单地调用 import sample,然后调用 sample.foo1(),而不必执行 from sampledir import sampleimport sampeldir.sample。例如,在使用 HTTP 库 requests 时,只需导入它并调用 requests.get(url)requests.requests.get('url') 不是必需的,就像在 urllib 中一样。如果我希望包被命名为 sample,正确的目录命名和安排是什么?

首先,我认为您误解了包和项目之间的区别。你的目录结构应该是这样的

arbitrary_name_of_project/
 - setup.py
 - README.rst
 - LICENSE.rst
 - package_name/
    -__init__.py
    -sample.py
    -utils.py

Python 包 "marked" 存在文件 __init__.py。 Python 搜索他的 PYTHONPATH 并寻找文件 __init__.py 的所有目录(简单地说,它实际上要复杂得多)。这些是您可以在 运行 时间内导入的包。

在我们的例子中,只有 package_name 目录会安装到 PYTHONPATH 的某处。因此,一旦安装(通过 setup.pydisutilssetuptools),您可以输入

import package_name

现在,您可以调用任意 class 或函数或此包中任何模块的任何内容,例如

package_name.sample.func1()

如果你想避免在调用中输入 package_name.sample,你可以将此行放在 __init__.py

from .sample import func1

函数 func1 将在 "import time" 期间放入您的全局名称 space 中。当在您的程序中执行 import package_name 时会发生这种情况。这个谜团可以通过每次导入包时执行 __init__.py 文件来解决。

有时候还要吐槽一下结构。您可以拥有 "nested" 个包(即您需要导入的包中的包)。还有 namespace 包,你可以在多个目录中 "spit" 一个包。世界是多样的。 :)

免责声明

我在没有测试我提供的代码的情况下写的。可能会有小错别字,但我希望这个故事或多或少是正确的。如有错误请指正