python - 从 Python 解释器运行时获取 "ImportError: attempted relative import with no known parent package"

标签 python python-import

我正在使用 Flask 创建模块化应用 blueprints特征。结果,我的目录结构是这样的:

project
    __init__.py
    config.py
    mould.py
    modules
        __init__.py
        core
            __init__.py
            core.py
            db.py
            models.py

不要将此处的模块目录与 Python 模块混淆,它们用于为我的项目提供模块化结构(核心模块、foo 模块、bar 模块等)。现在,模块目录中的每个文件夹(以及其中的同名模块,例如 core.core)都动态导入到我的主 flask 应用程序(mould.py)中这样做:

for item in os.listdir("modules"):
    if not os.path.isfile("modules" + os.sep + item) and not item.startswith("__"):
        ppath = "modules" + "." + item
        fullpath = "modules" + "." + item + "." + item
        module = importlib.import_module(fullpath)
        app.register_blueprint(module.app)
        print("Registered: " + ppath)

因此,我无法在像 db.py 这样的模块脚本中执行此操作:

import models

由于在项目级别执行整个模块时会出现路径错误,所以我必须这样做:

from . import models

这解决了问题,我能够成功导入所有模块。但是,当我转到核心模块目录进行一些故障排除并启动 python 解释器时,它不允许我导入 db 模块:

>>> import db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "db.py", line 7, in <module>
    from . import models
ImportError: attempted relative import with no known parent package

有解决办法吗?那么,我可以在代码和解释器中成功导入 db 模块吗?

最佳答案

我知道我迟到了,但我想我已经找到了解决这个问题的办法。希望这对从事大型 Python 项目的其他人有用。

诀窍是尝试一种导入格式,如果第一种格式失败,则回退到另一种格式。

方法一

db.py

try:
    # Assume we're a sub-module in a package.
    from . import models
except ImportError:
    # Apparently no higher-level package has been imported, fall back to a local import.
    import models

从好的方面来说,这种方法非常简单,但扩展性不佳(模块名称重复)。可以通过以编程方式导入来改进缩放。

方法二(不推荐)

db.py

import importlib

root = 'project.modules.core'
my_modules = ['core', 'models']
for m in my_modules
    try:
        globals()[m] = importlib.import_module(root + '.' + m)
    except ImportError:
        globals()[m] = importlib.import_module(m)

globals()是全局符号表。

当然,现在需要在每个模块中复制此功能。我不确定这实际上是对第一种方法的改进。但是,您可以将此逻辑分离到它自己的独立包中,该包位于 pythonpath 上的某处。 .

方法三

package_importer.py

import importlib

def import_module(global_vars, root, modules):
    for m in modules
        try:
            global_vars[m] = importlib.import_module(root + '.' + m)
        except ImportError:
            global_vars[m] = importlib.import_module(m)

db.py

import package_importer

root = 'project.modules.core'
my_modules = ['core', 'models']
package_importer.import_module(globals(), root, my_modules)

关于python - 从 Python 解释器运行时获取 "ImportError: attempted relative import with no known parent package",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45088071/

相关文章:

python - 从兄弟目录导入模块以与 py.test 一起使用

python - 使用 Python + Kivy 进行编码 - 桌面应用程序界面

python - 将 dbf 文件附加到一个 dbf 文件

python - 为每一行向 DF 添加唯一组,包括来自其他列的总和

python - 如何在 python 中转换分组数据框

Python跨模块全局变量

python - 在 Python 3 中绘制罂粟花

tensorflow - 为什么使用 "slim = tf.contrib.slim"而不是通常的 import slim ?

python-import - 如何在colab上安装utils?

python - Django 循环导入