我可以为 python 子包添加别名,以便使用点表示法从顶级包访问吗?

问题描述 投票:0回答:1

这可能是一个非常基本的包装问题,但我只是找不到答案。

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
错误。

有什么建议吗?有办法做我提议的事情吗?这是否违反最佳实践?我应该放弃向后兼容性吗?

python python-import python-packaging
1个回答
0
投票

这将正确处理

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 个选择:

  1. mypackage.target_package
    作为包保留,并将其中的文件从
    import *
    中相应的“真实”模块更改为
    mypackage.subpackage.target_package
  2. (不推荐)当加载任何模块/包时,您可以尝试将
    mypackage.target_package
    插入
    sys.modules
    (Python 实际上在内部为
    os.path
    执行此操作),但要使其工作,需要在用户的代码,首先导入您的其他模块/包之一,并且
    import mypackage.target_package
    仅在 之后 发生,请参阅 https://stackoverflow.com/a/2725195/19115554 了解更多详细信息。
© www.soinside.com 2019 - 2024. All rights reserved.