Python:导入包含的包

62
在一个包内的模块中,我需要使用在该包的__init__.py中定义的函数。我应该如何在位于该包内的模块中导入该包,以便我可以使用该函数?导入__init__将不会导入该包,而是导入名为__init__的模块,从而导致具有不同名称的两个副本...是否有一种Pythonic方式来实现这个呢?
5个回答

47

另外,从 Python 2.5 开始,相对导入也成为可能。例如:

from . import foo

引用自http://docs.python.org/tutorial/modules.html#intra-package-references:


从Python 2.5开始,除了上面提到的隐式相对导入外,您还可以使用“from module import name”的形式编写显式相对导入。这些显式相对导入使用前导点来指示涉及相对导入的当前和父包。例如,在周围模块中,您可能会使用:

from . import echo
from .. import formats
from ..filters import equalizer

4
这并没有回答如何从__init__.py导入的问题。 - BrenBarn
1
@BrenBarn:然而这是导入它的方式;当你导入时,__init__.py文件作为有效的命名空间。你永远不应该直接导入__init__.py - Martijn Pieters

23

这并不能完全回答你的问题,但我建议你将该函数从__init__.py文件中移出,并放到该包内的另一个模块中。然后你可以轻松地在其他模块中导入该函数。如果需要,在__init__.py文件中添加一个导入语句,在包被导入时也会导入该函数。


1
我意识到我可以做到这一点,但它似乎相当混乱和不符合Python的风格。 - guy
4
这个为什么不符合 Python 的编程规范呢?难道替代方案会更加混乱,因为 init.py 实际上并不是一个模块? - Greg Case
16
在Python中,使用包内的common.py非常普遍。 - cdleary
我一直在摸索,但没有找到更好的方法。 - abyx

5
如果包名为testmod,则您的初始化文件应该是testmod/__init__.py,而您在包中的模块为submod.py。因此,在submod.py文件中,您只需要说import testmod,然后使用在testmod中定义的任何内容。

1
在Django中,文件manage.py有from django.core.management import execute_manager,但execute_manager不是一个模块。它是management目录下的__init__.py模块中的一个函数。

1

我不完全确定情况是什么,但这可能会解决你的“不同名称”问题:

import __init__ as top
top.some_function()

或者呢?

from __init__ import some_function
some_function()

3
这确实可行,但至少在 cPython 2.7 中,解释器认为 __init__top 是不同的模块,因此会加载两次 __init__.py 文件。 - dimo414
2
这是一种隐式相对导入方式,因此在Python 3中无法使用,在Python 2中也是不良实践。 - habnabit
1
这仍然会创建 sys.modules['__init__']。基本上,__init__.py 模块不应该被直接导入。应该导入包(即目录名称)。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接