这可能是一个非常基本的包装问题,但我只是找不到答案。
TLDR:我想知道是否可以通过使用点符号别名
mypackage.subpackage.target_package
来访问嵌套子包(位于mypackage.target_package
)。也就是说,您可以将 mypackage.target_package
添加到 mypackage
的顶级命名空间吗?
完整解释: 我正在开发一个Python包,最初具有以下结构:
mypackage
├── __init__.py
├── subpackage
│ ├── __init__.py
│ └── module_b.py
└── target_package
├── __init__.py
└── module_c.py
这样,target_package就可以访问了,如下:
from mypackage.target_package import *
。但是,我正在做一些重构并将 target_package 移动到子包中。
新结构:
mypackage
├── __init__.py
└── subpackage
├── __init__.py
├── module_b.py
└── target_package
├── __init__.py
└── module_c.py
问题是,我不想破坏与以前访问
target_package
的方式的向后兼容性,即我希望能够通过简单地调用 mypackage.subpackage.target_package
来访问
mypackage.target_package
我在三个 _init_.py 文件中尝试了许多不同的导入组合,并且仅成功地使
target_package
(如 module_c
)中的模块在此级别可访问。
目前最里面的_init_.py,内容是
# mypackage/subpackage/target_package/__init__.py
from . import
在子包内,init文件是空白的
# mypackage/subpackage/__init__.py
在 mypackage 的顶层 init 中:
# mypackage/__init__.py
from .subpackage import target_package
有了这些,我就可以打电话了
from mypackage import target_package
没有任何问题,但是当我尝试打电话时import mypackage.target_package
它会抛出一个 ModuleNotFound
错误。
有什么建议吗?有办法做我提议的事情吗?这是否违反最佳实践?我应该放弃向后兼容性吗?
这将正确处理
from mypackage import target_package
和 import mypackage.target_package
,但不能正确处理 import mypackage.target_package.module_c
:
mypackage
├── __init__.py
├── target_package.py
└── subpackage
├── __init__.py
├── module_b.py
└── target_package
├── __init__.py
└── module_c.py
在
target_package.py
:
from .subpackage.target_package import *
在最里面
__init__.py
:
# All the things you want to make available in target_package e.g.
from .module_c import some_function_in_module_c
...
所以现在,所有这些都将起作用:
from mypackage.target_package import mod_c_func
from mypackage import target_package
import mypackage.target_package
但这些都不会:
from mypackage.target_package.module_c import mod_c_func
import mypackage.target_package.module_c
如果您希望
import mypackage.target_package.module_c
仍然有效,您有 2 个选择:
mypackage.target_package
作为包保留,并将其中的文件从 import *
中相应的“真实”模块更改为 mypackage.subpackage.target_package
。mypackage.target_package
插入 sys.modules
(Python 实际上在内部为 os.path
执行此操作),但要使其工作,需要在用户的代码,首先导入您的其他模块/包之一,并且 import mypackage.target_package
仅在 之后 发生,请参阅 https://stackoverflow.com/a/2725195/19115554 了解更多详细信息。