0

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

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

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

目前__init__并且setup无人居住。sample.py是包的任何用户都想要导入的文件。它包含不同功能形式的 api:foo1, foo2.

utils.py包含smaple.py. 后者包含一个声明import utils

放置在该目录下的任何脚本sampledir都可以轻松地import sample将小说用作sample.foo1(). 走出这个目录,我可以调用import sampledir,但不能调用import sample,这是预期的。所以我需要做from sampledir import sample。这会导致import utils行中的错误sample.py

ImportError: No module named 'utils'

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

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

此外,什么样的目录结构将允许已安装软件包的用户简单地调用import sample后跟sample.foo1(),而不必执行from sampledir import sampleor import sampeldir.sample。例如,在使用 HTTP 库requests时,只需导入它并调用requests.get(url). requests.requests.get('url')不是必需的,就像在urllib. 如果我想命名包,正确的目录命名和安排是sample什么?

4

1 回答 1

0

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

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

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

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

import package_name

现在,您可以从这个包中的任何模块调用任意类或函数或任何东西,例如

package_name.sample.func1()

如果你想避免输入package_name.sample你的电话,你可以把这行放在__init__.py

from .sample import func1

然后,该函数func1将在“导入时间”期间放入您的全局名称空间。import package_name在您的程序中执行时会发生这种情况。这个谜团可以通过__init__.py每次导入包时执行文件这一事实来解决。

有时甚至需要更多地吐出结构。您可以拥有“嵌套”包(即需要导入的包中的包)。还有命名空间包,您可以在其中在多个目录中“吐出”一个包。世界是多种多样的。:)

免责声明

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

于 2016-07-12T12:15:59.960 回答