Python can't import module from package

泄露秘密 提交于 2020-01-25 10:20:10

问题


I have a flask restful project with the following layout (file names changed for convenience)

myproject/
    __init__.py
    app.py
    common/
        __init__.py
        util.py
    foo/
        __init__.py
        main.py
        utilities.py

foo/ is just a folder containing code for one of the API endpoints, I'm planning to add others in the future, for this reason I have common/util.py file which contains reusable functions that I will use with other API endpoints.

foo/main.py

from flask_restful import Resource, request

from utilities import Analysis

class Foo(Resource):
    def get(self):      
        pass

in foo/utilities.py I have classes with methods that get some data, I import those classes to foo/main.py to return JSON response

classes in foo/utilities.py also uses some functions from common/util.py but when I try to import something from common/util.py to foo/utilities.py I get import common.util ModuleNotFoundError: No module named 'common'

What could be causing this? I tried importing various ways: from common.util import my_func from .common.util import my_func from myproject.common.util import my_func

but none worked.

This is myproject/app.py in case it matters:

from flask import Flask
from flask_restful import Api

from foo.main import Foo

app = Flask(__name__)
api = Api(app)

api.add_resource(Foo, '/Foo')

if __name__ == "__main__":
    app.run()

I'm doing all of this in activated virtualenv if it matters


回答1:


from common.util import my_func

In Python 3 this is an absolute import, that is, the directory with common/ subdirectory must be in sys.path. In your situation it's certainly a wrong approach.

from .common.util import my_func

This import expects common to be a subdirectory of foo which is also not the case.

from myproject.common.util import my_func

This is finally the best approach but for it to work the parent directory of myproject/ subdirectory must be in sys.path. Either you install the entire myproject or add the parent directory to $PYTHONPATH environment variable or add the directory to sys.path in foo/main.py. Something like:

PYTHONPATH=/home/to/parentdir /home/to/parentdir/myproject/foo/main.py

or

import sys
sys.path.insert(0, '/home/to/parentdir')

/home/to/parentdir is the directory where myproject/ is.

After installing myproject or adding its parent directory to sys.path you can also use relative import. You need to remember that common is a sibling package comparing to foo so the import must be not from .common but from ..common:

from ..common.util import my_func


来源:https://stackoverflow.com/questions/55079846/python-cant-import-module-from-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!