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
解决方案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