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:foo1
、foo2
。
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 sample
或 import 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.py
和 disutils
或 setuptools
),您可以输入
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" 一个包。世界是多样的。 :)
免责声明
我在没有测试我提供的代码的情况下写的。可能会有小错别字,但我希望这个故事或多或少是正确的。如有错误请指正
我正在发布一个 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
。这会导致 sample.py
import utils
行出错
ImportError: No module named 'utils'
在某些地方,我看到同一目录中的文件 import .utils
。但是当我尝试这样做时,它会导致语法错误。
为什么我不能从 sampledir 外部导入 sample.py
?
此外,什么样的目录结构可以让安装了该软件包的用户能够简单地调用 import sample
,然后调用 sample.foo1()
,而不必执行 from sampledir import sample
或 import 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.py
和 disutils
或 setuptools
),您可以输入
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" 一个包。世界是多样的。 :)
免责声明
我在没有测试我提供的代码的情况下写的。可能会有小错别字,但我希望这个故事或多或少是正确的。如有错误请指正