2015-06-10 16 views
6

Wystąpił problem z okrężnym importowaniem, więc przeniosłem import wzorca poniżej definicji mojej aplikacji. Nadal jednak wystąpił błąd importu.Jaki jest poprawny sposób rozwiązania tego błędnego błędu importu kolistego za pomocą schematu kolby?

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 

Jeśli przenieść import Blueprint i rejestracyjne if __name__ == '__main__':, problem zniknie, ale nie jestem pewien, czy to dobry pomysł.

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

Czy to jest właściwy sposób rozwiązania problemu, czy istnieje inne rozwiązanie?


oryginalny app.py bez __main__ "naprawić":

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): 
    # ... 

Moja struktura pliku jest:

/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

Poprzez umieszczenie importu i wywołanie funkcji 'register_blueprint' wewnątrz instrukcji if, twój projekt nie zostanie zarejestrowany, jeśli uruchomisz aplikację bez bezpośredniego wykonywania pliku (np. Z uwsgi). – dirn

+0

@dirn Czy nie to właśnie zrobiłem, umieszczając import wewnątrz 'if __name__ == '__main __':'? – benjaminz

+0

Mówi, że poprzez umieszczanie rzeczy w tym strażniku, to tylko wtedy, gdy wykonasz plik bezpośrednio. Podczas korzystania z prawdziwego serwera aplikacji tak się nie stanie, więc wszystkie twoje plany będą "zaginione". – davidism

Odpowiedz

2

Masz okrągły import w kodzie. W oparciu o traceback:

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

W oparciu o te kolejność zdarzeń opublikowany app.py nie jest tym, który faktycznie powoduje Twój problem. Obecnie, app nie został zdefiniowany przed zaimportowaniem views, więc gdy w dalszym ciągu łańcucha próbuje uzyskać app, to nie jest jeszcze dostępna.

trzeba zrestrukturyzować swój projekt tak, że wszystko zależy od app jest importowany poapp jest zdefiniowana. Z twojego pytania wynika, że ​​Ci się zdawało, ale być może import został zapisany powyżej app, który przegapiłeś.


Prawdopodobnie nie ma to związku, ale obecnie używasz "względnego" przywozu, który jest odradzany. Zamiast wykonywać from views import site itd., Powinieneś wykonać ścieżkę bezwzględną: from app.views import site lub ścieżkę względną: from .views import site.


Aby odpowiedzieć na pytanie początkowe „używa __main__ importować plany dobry pomysł?”, To nie jest. Problem polega na tym, że zabezpieczenie __main__ jest wykonywane tylko wtedy, gdy moduł jest uruchamiany bezpośrednio. Po wdrożeniu tego przy użyciu prawdziwego serwera aplikacji, takiego jak uWSGI lub Gunicorn, żaden z twoich projektów nie zostanie zaimportowany ani zarejestrowany.

Powiązane problemy