包的相对导入__init__.py

zwo*_*wol 13 python packages python-module

假设我有一个包含两个子模块的包,并且__init__.py本身也包含大量代码:

pkg/__init__.py
pkg/foo.py
pkg/bar.py
Run Code Online (Sandbox Code Playgroud)

并且,为了使计划的未来重构更容易,我希望包的组件专门使用相对导入来相互引用.特别是,import pkg永远不应该出现.

foo.py我能做到

from __future__ import absolute_import
from . import bar
Run Code Online (Sandbox Code Playgroud)

访问bar.py模块,反之亦然.

问题是,我以__init__.py这种方式写什么来导入? 我想要完全相同的效果import pkg as local_name,只需要不必指定绝对名称pkg.

#import pkg as local_name
from . import ??? as local_name
Run Code Online (Sandbox Code Playgroud)

更新:受到maxymoo的回答的启发,我试过了

from . import __init__ as local_name
Run Code Online (Sandbox Code Playgroud)

这不会设置local_name为定义的模块__init__.py; 它取而代之的是看起来是该模块__init__ 方法的绑定方法包装器.我想我能做到

from . import __init__ as local_name
local_name = local_name.__self__
Run Code Online (Sandbox Code Playgroud)

得到我想要的东西,但(a)哎呀,(b)这让我担心模块还没有完全初始化.

答案需要在工作的Python 2.7和Python 3.4+.

是的,挖空可能会更好__init__.py,只是让它从子模块重新导出东西,但这还不可能发生.

max*_*moo 4

dunders 没有什么特别的(他们只是在编写自己的模块/函数名称时感到沮丧);你应该能够做到

from .__init__ import my_function as local_name
Run Code Online (Sandbox Code Playgroud)

  • 显式导入 `__init__` 模块会重新执行该模块,从而产生两个不同的模块(`pkg is pkg.__init__` 为 False)。每个都有自己的命名空间。如果您更改“pkg”中的某些内容(例如“pkg.config.setSomeValue(...)”),它不会影响“pkg.__init__”中的对应内容。 (3认同)
  • @mata 这开始感觉像是一个错误报告:-/ (2认同)