Python:如何使用相对导入导入包root

时间:2013-12-22 06:06:05

标签: python import

我在python包的顶级__init__.py中定义了大量名称。我想使用 relative import来导入这个命名空间,因为我不一定知道运行时的包名(它甚至可能被用作其他包的子包)。例如,请使用以下包:

my_package/
    __init__.py
        a = 1
        b = 2
        ...
    my_module.py
        from . import ??? as my_package
        print(my_package.a)

如何修复my_module中的import语句,使print语句正常工作?我也宁愿避免from . import a, b, ...;我只想将整个包命名空间作为一个变量导入。

我尝试了from . import __init__ as my_package,但在这种情况下,my_package作为方法包装器导入,而不是模块。我也试过了my_module = __import__(__package__),它仅适用于my_package不是子包的情况。

似乎应该有一个简单的答案..

3 个答案:

答案 0 :(得分:2)

您可以使用__package__了解包名称,importlib.import_module;这适用于子包。

import importlib
pkg = importlib.import_module(__package__)
print(pkg.a)

答案 1 :(得分:1)

__init__.py用于您要公开的名称,可以从包的顶层导入。在这种情况下,您使用它来在内部导入名称,即在您的包中,因此问题。

因此,您应该将包内部使用的所有名称/定义放在另一个文件中,例如: defs.py,然后从那里导入:

from .defs import foo, bar, baz

并确保只留下__init__.py您希望顶级暴露给外界的名字。

编辑:澄清一下,在__init__.py中,您不需要复制名称/定义,只需以完全相同的方式导入它们:

from .defs import foo, bar

或者

from .defs import *  # not recommended, of course

然后,从包外面,可以从packege的顶层导入名称,如下所示:

from my_package import foo, bar

或者

from path.to.my_package import foo, bar

答案 2 :(得分:0)

据我所知,没有办法使用相对导入将包__init__.py作为模块导入。

如果你的包中有各种通用对象,你的目标是(正如你在评论中所说的那样)“让它们易于使用”,只需将它们放在自己的模块中即可。 from . import miscPackageStuff并不比from . import __init__更方便(如果你能做到的话)。

如果您还希望在不显式导入子模块的情况下从外部访问这些常规对象,只需在from .miscPackageStuff import foo, bar, baz中执行__init__.py