Getting “ImportError: attempted relative import with no known parent package” when running from Python Interpreter

后端 未结 2 894
滥情空心
滥情空心 2021-01-04 05:20

I\'m creating a modular app using Flask blueprints feature. As a result, my directory structure is like this:

project
    __init__.py
    config.py
    mould         


        
2条回答
  •  一生所求
    2021-01-04 05:41

    I know I'm late to the party, but I think I've found a solution to this problem. Hopefully this will be useful to someone else working on a large Python project.

    The trick is to try one import format and fall back to the other format if the first fails.

    Approach 1

    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
    

    On the plus side, this approach is pretty simple, but doesn't scale well (module names are duplicated). Scaling can be improved by importing programmatically.

    Approach 2 (not recommended)

    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() is the global symbol table.

    Of course, now this functionality needs to be duplicated in every module. I'm not sure that's actually an improvement over the first approach. However, you can separate this logic out into its own independent package that lives somewhere on pythonpath.

    Approach 3

    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)
    

提交回复
热议问题