使用 sub-modules 打包模块的最佳实践 - 大多数使用相同的库
Best practice for packaging modules with sub-modules - most using the same libraries
我目前正在打包我自己的模块以供分发。总的来说一切正常,但是 fine-tuning/best-practice 用于构建 sub-modules 给我带来了一些麻烦。
假设模块结构为:
mdl
├── mdl
│ ├── __init__.py
│ ├── core.py
| ├── sub_one
| | ├── __init__.py
| | └── core_sub_one.py
| └── sub_two
| ├── __init__.py
| └── core_sub_two.py
├── README
└── setup.py
核心文件headers
以core.py
的header开头:
import numpy as np
...some fairly large module code...
以及 core_sub_one.py
和 core_sub_two.py
的 header 都以:
开头
import numpy as np
from .. import core as cr
所以所有子模块都需要np
和cr
。
初始化.py结构
mdl/__init__.py
(core-level) 看起来像:
from . import sub_one as so
from . import sub_two as st
和两个子模块的 __init__.py
看起来像(将 one
替换为 two
另一个子模块):
from . import core_sub_one
from .core_sub_one import *
我 "learnt" 这个结构来自 numpy
,见 f.i。 numpy/ma/__init__.py
问题描述
现在我在 运行 setup.py
和使用 import mdl
.
导入我的模块后遇到了一些问题 submodule-access
我现在可以使用 f.i 访问我的子模块。 mdl.so.some_function_in_sub_one()
。这是预期的,也是我想要的。
但是我也可以访问顶级模块cr
和 numpy
with mdl.so.cr
和 mdl.so.np
, 我想避免的。 有什么办法可以避免这种情况吗?
如果不是:像这样的 importing/connecting 模块和子模块有什么缺点吗?
And 是否有关于如何在 sub-modules 中导入像 numpy
这样的库的最佳实践,当它们在 all 中需要时 个子模块?
编辑:
因为有些人似乎对要求 最佳实践 是 意见基础 (我知道并且我打算这样做,因为恕我直言大多数设计现实生活中的决策不是明确的二进制 1-0 决策),我必须添加:
我想遵守 scipy
中使用的模块打包样式,更具体地说 numpy
,包环境。因此,如果这些软件包找到了我提出的任何问题的解决方案,这将是我最受欢迎的解决方案。
第一件事:
from .core_sub_one import *
不要这样做。是的,即使您在某些 "big name" 包中看到它,也请在某些教程或其他内容中阅读它。这是 officially considered bad practice,并且有充分的理由(根据经验,这是一个维护地狱)。
如果你真的坚持这样做(但说真的,不要这样做),至少 define an explicit __all__
var in those modules 这样你就可以控制暴露的名称(这有助于记录模块的 API).
But I can also access the top level module cr and numpy with mdl.so.cr and mdl.so.np, which I want to avoid. Is there any way to avoid this?
不是真的。如果你真的担心它,你可以在你的子模块中将这些名称作为 "protected" 导入:
# core_sub_xxx.py
import numpy as _np
from .. import core as _cr
(当然你必须替换所有出现的 'np' 和 'cr' 但任何半正经的文本编辑器都可以做到这一点)
这不会阻止对 mysubmodule._cr
或 mysubmodule._np
的访问,但至少清楚表明不应访问这些名称。
但实际上,这不是什么大问题,只要您的 API 有明确记录即可。
我目前正在打包我自己的模块以供分发。总的来说一切正常,但是 fine-tuning/best-practice 用于构建 sub-modules 给我带来了一些麻烦。
假设模块结构为:
mdl
├── mdl
│ ├── __init__.py
│ ├── core.py
| ├── sub_one
| | ├── __init__.py
| | └── core_sub_one.py
| └── sub_two
| ├── __init__.py
| └── core_sub_two.py
├── README
└── setup.py
核心文件headers
以core.py
的header开头:
import numpy as np
...some fairly large module code...
以及 core_sub_one.py
和 core_sub_two.py
的 header 都以:
import numpy as np
from .. import core as cr
所以所有子模块都需要np
和cr
。
初始化.py结构
mdl/__init__.py
(core-level) 看起来像:
from . import sub_one as so
from . import sub_two as st
和两个子模块的 __init__.py
看起来像(将 one
替换为 two
另一个子模块):
from . import core_sub_one
from .core_sub_one import *
我 "learnt" 这个结构来自 numpy
,见 f.i。 numpy/ma/__init__.py
问题描述
现在我在 运行 setup.py
和使用 import mdl
.
导入我的模块后遇到了一些问题 submodule-access
我现在可以使用 f.i 访问我的子模块。 mdl.so.some_function_in_sub_one()
。这是预期的,也是我想要的。
但是我也可以访问顶级模块cr
和 numpy
with mdl.so.cr
和 mdl.so.np
, 我想避免的。 有什么办法可以避免这种情况吗?
如果不是:像这样的 importing/connecting 模块和子模块有什么缺点吗?
And 是否有关于如何在 sub-modules 中导入像 numpy
这样的库的最佳实践,当它们在 all 中需要时 个子模块?
编辑:
因为有些人似乎对要求 最佳实践 是 意见基础 (我知道并且我打算这样做,因为恕我直言大多数设计现实生活中的决策不是明确的二进制 1-0 决策),我必须添加:
我想遵守 scipy
中使用的模块打包样式,更具体地说 numpy
,包环境。因此,如果这些软件包找到了我提出的任何问题的解决方案,这将是我最受欢迎的解决方案。
第一件事:
from .core_sub_one import *
不要这样做。是的,即使您在某些 "big name" 包中看到它,也请在某些教程或其他内容中阅读它。这是 officially considered bad practice,并且有充分的理由(根据经验,这是一个维护地狱)。
如果你真的坚持这样做(但说真的,不要这样做),至少 define an explicit __all__
var in those modules 这样你就可以控制暴露的名称(这有助于记录模块的 API).
But I can also access the top level module cr and numpy with mdl.so.cr and mdl.so.np, which I want to avoid. Is there any way to avoid this?
不是真的。如果你真的担心它,你可以在你的子模块中将这些名称作为 "protected" 导入:
# core_sub_xxx.py
import numpy as _np
from .. import core as _cr
(当然你必须替换所有出现的 'np' 和 'cr' 但任何半正经的文本编辑器都可以做到这一点)
这不会阻止对 mysubmodule._cr
或 mysubmodule._np
的访问,但至少清楚表明不应访问这些名称。
但实际上,这不是什么大问题,只要您的 API 有明确记录即可。