2015-06-10 9 views
6

Ich hatte ein Problem mit einem kreisförmigen Import, also habe ich meinen Blueprint-Import unter meine App-Definition verschoben. Ich habe jedoch immer noch einen Importfehler.Was ist der richtige Weg, um diesen zirkulären Importfehler mit einem Flask Blueprint zu lösen?

Traceback (most recent call last): 
    File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2217, in <module> 
    globals = debugger.run(setup['file'], None, None) 
    File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1643, in run 
    pydev_imports.execfile(file, globals, locals) # execute the script 
    File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module> 
    from views import site 
    File "/Users/benjamin/Documents/Projects/website/server/app/views.py", line 2, in <module> 
    from models import User 
    File "/Users/benjamin/Documents/Projects/website/server/app/models.py", line 3, in <module> 
    from database_setup import db 
    File "/Users/benjamin/Documents/Projects/website/server/app/database_setup.py", line 1, in <module> 
    from app import app 
    File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module> 
    from views import site 
ImportError: cannot import name site 

Wenn ich den Bauplan Import und Registrierung if __name__ == '__main__': bewegen, geht das Problem weg, aber ich bin nicht sicher, ob dies eine gute Idee ist.

if __name__ == '__main__': 
    from views import site 
    app.register_blueprint(site) 
    app.run() 

Ist dies der richtige Weg, um das Problem zu lösen, oder gibt es eine andere Lösung?


original app.py ohne __main__ "fix":

from flask import Flask 

app = Flask(__name__) 

from views import site 
app.register_blueprint(site) 

if __name__ == '__main__': 
    app.debug = True 
    app.run() 

views.py:

from flask import Blueprint, render_template 

site = Blueprint('site', __name__, template_folder='templates', static_folder='static') 

@site.route('/', methods=['GET', 'POST']) 
def index(): 
    return render_template('index.html') 

database_setup.py:

from app import app 
from flask_mongoengine import MongoEngine 

app.config['MONGODB_SETTINGS'] = {'db': 'mst_website'}  
db = MongoEngine(app) 

models.py:

from database_setup import db 

class User(db.Document): 
    # ... 

Meine Dateistruktur ist:

/server 
    |-- requirements.txt 
    |-- env/ (virtual environment) 
    |-- app/ (my main app folder) 
     |-- static/ 
     |-- templates/ 
     |-- __init__.py 
     |-- app.py 
     |-- database_setup.py 
     |-- models.py 
     |-- views.py 
+1

Durch den Import und den Aufruf von 'register_blueprint' im if wird Ihr Entwurf nicht registriert, wenn Sie Ihre Anwendung ausführen, ohne die Datei direkt auszuführen (z. B. mit uwsgi). – dirn

+0

@dirn Ist das nicht, was ich hier gemacht habe, indem ich den Import in 'if __name__ == '__main __' gestellt habe:'? – benjaminz

+0

Er sagt, dass wenn man Sachen in diesen Wächter legt, es nur ausgeführt wird, wenn man die Datei direkt ausführt. Wenn Sie einen echten App-Server verwenden, wird das nicht passieren, also werden alle Ihre Blaupausen "fehlen". – davidism

Antwort

2

Sie haben einen kreisförmigen Import in Ihrem Code. Basierend auf dem Rückverfolgungs:

  1. app.py tut from views import site
  2. views.py tut from models import User
  3. models.py tut from database_setup import db
  4. database_setup.py tut from app import app
  5. app.py tut from views import site

Basierend auf dieser Reihenfolge der Ereignisse ist die app.py, die Sie gepostet haben, nicht diejenige, die Ihr Problem tatsächlich verursacht. Gerade jetzt app wurde nicht definiert, bevor views importiert wird, also wenn weiter unten die Kette versucht, app zu erhalten, ist es noch nicht verfügbar.

Sie müssen Ihr Projekt neu strukturieren, so dass alles, was nach importiert auf app hängt app definiert ist. Von deiner Frage scheint es, dass du denkst, dass du es getan hast, aber vielleicht gibt es noch einen Import, der über app geschrieben wurde, den du verpasst hast.


Wahrscheinlich nicht verwandte, aber Sie sind zur Zeit als „relative“ Importe, die entmutigt sind. Anstatt from views import site usw. auszuführen, sollten Sie einen absoluten Pfad eingeben: from app.views import site oder einen relativen Pfad: from .views import site.


die anfängliche Frage „__main__ wird mit einer guten Idee zu importieren Pläne?“ Beantworten zu können, ist es nicht. Das Problem dabei ist, dass der __main__ Guard nur ausgeführt wird, wenn Sie das Modul direkt ausführen. Wenn Sie diese mit einem echten App-Server wie uWSGI oder Gunicorn bereitstellen, wird keiner Ihrer Blaupausen importiert oder registriert.

Verwandte Themen