4

I learn from Larger Applications.In this document, It says: "all the view functions (the ones with a route() decorator on top) have to be imported in the init.py file. Not the object itself, but the module it is in."
I don't know why should when I do this: from . import views,It succeed.Though from views import * can also work well.
I organize these file like this:

myapplication/
  runner.py
  myflask/
    __init__.py
    views.py
    templates/
    static/
    ...

runner.py:

from testFlask import app
app.run()

myflask/__init__.py:

from flask import Flask
app = Flask(__name__)
from . import views # why this can work????

myflask/views.py:

from . import app
@app.route('/')
def index():
    return 'Hello World!'

and I run it:

$ cd myapplication
$ python runner.py

It's OK to run this Flask app. However I want to know why from . import views can solve this circle import problem in flask? And why the doc says: Not the object itself, but the module it is in????

However,when I do like this:

#some_dir/
#  application.py
#  views.py

#application.py
from flask import Flask
app = Flask(__name__)
import views # it doesn't work
# from views import * # it works
app.run()

#views.py
from application import app
@app.route('/')
def index():
    return 'Hello World!'

#run it
$ python application.py

It doesn't work.

zjyExcelsior
  • 63
  • 1
  • 6

3 Answers3

1

It is a circular import. But in your case, the variable that might have been problematic (app) has already been defined in the imported script, so the import just causes the first "app" instance to be overwritten by the imported "app" instance. Which has no practical effect.

For details about this circular import situation, please read this post.

If you want to follow the pattern for a large flask application, you should look into blueprints and application factories.

Community
  • 1
  • 1
lesingerouge
  • 1,160
  • 7
  • 14
  • Great."When you import a module (or a member of it) for the first time, the code inside the module is executed sequentially like any other code;" in the [post](http://stackoverflow.com/questions/22187279/python-circular-importing) is good!I have understood,thank u. – zjyExcelsior May 09 '16 at 11:25
1

It's not the specific command that solves the problem, but the order of the commands.

The trick is that you import the views after you created the app variable in your main script, so when the view script imports the main script the variable is already defined.

If you would try to import the views above declaring the app variable it would not work because it would cause an import loop and could not find the app variable.

Bastian
  • 10,403
  • 1
  • 31
  • 40
  • I know it's the order of the commands to solve it, It's not my question.My question is: why `from . import views.py` in __init__.py works. However when I do this in an app_flask.py,I write `import views`, It doesn't work. – zjyExcelsior May 09 '16 at 10:29
1

Your project structure defines how the import would work best.

Here's an example of "A bit larger type of application" where you can use blueprints that defines a collection of views, templates, static files and other elements that can be applied to an application:

https://github.com/pallets/flask-website/tree/master/flask_website

Kind regards

Jalal
  • 407
  • 3
  • 5
  • Maybe you didn't see my description carefully. – zjyExcelsior May 09 '16 at 10:27
  • Well, maybe "When you import a module (or a member of it) for the first time, the code inside the module is executed sequentially like any other code;" is a good answer rather than yours.Thanks however. – zjyExcelsior May 13 '16 at 10:17