2017-09-18 15 views
0

私はFlaskのプロジェクトに取り組んでおり、循環的なインポートに問題があります。フラスコ - 大きなアプリで循環輸入を防ぐにはどうすればいいですか?

マイアプリの構造は次のようになります。

. 
├── api 
│   ├── __init__.py 
│   ├── schema.py 
│   └── sender.py 
├── app.py 
├── config.py 
├── README.md 
├── run.sh 
├── static 
│   ├── css 
│   │   ├── base.css 
│   │   ├── index.css 
│   │   └── model.css 
│   └── index.html 
├── templates 
│   ├── base.html 
│   ├── model.html 
│   ├── schema_add.html 
│   ├── schema.html 
│   └── table.html 
└── views 
    ├── auth.py 
    ├── error_handler.py 
    ├── __init__.py 
    ├── model.py 
    ├── schema.py 
    └── table.py 

ソースコードはthis

Here's a trace of error: 
    Traceback (most recent call last): 
    File "./../anton_temp/app.py", line 3, in <module> 
    from views import * 
    File 
"/home/shubham1172/Documents/Anton/anton_temp/views/__init__.py", line 
16, in <module> 
    from .auth import * 
    File "/home/shubham1172/Documents/Anton/anton_temp/views/auth.py", 
line 4, in <module> 
    from app import setConnection, getConnection, closeConnection 
    File "/home/shubham1172/Documents/Anton/anton_temp/app.py", line 4, 
in <module> 
    from api import * 
    File "/home/shubham1172/Documents/Anton/anton_temp/api/__init__.py", 
line 13, in <module> 
    from .schema import * 
    File "/home/shubham1172/Documents/Anton/anton_temp/api/schema.py", 
line 5, in <module> 
    from app import getConnection 
ImportError: cannot import name 'getConnection' 
問題は、私は私のアプリで私の青写真(ビューおよびAPI)を含める必要がある

で提供されています。これらの青写真のための のinitファイルには、さらに今度はアプリからいくつかの機能を含める必要がありPYファイルが含まれています。

私は、外部ファイルにこれらの関数が含まれるようにどこかで読ん青写真から呼び出し、その後extension.pyと言うが、アプリで私の関数は、そのconfigオブジェクトのための「アプリ」に参照が含まれています。

これを修正するにはどうすればよいですか?

EDIT

としては、私は私のコードをリファクタリングする必要があります、と指摘しました。 Thisには同じ問題の例が示され、解決策が示されました。しかし、私の拡張関数は、アプリケーションのconfigへの呼び出しを必要とする、すなわち

A.py

import B 
from C import dependency 

B.py

from C import dependency 

C.py

def dependency(): 
    #Use A.config here <---------- 
    pass 

これを解決する方法はありますか?

EDIT

私は私のコードをリファクタリングすることによってそれを解決しました。 私はapp.configを簡単な関数呼び出しで別のファイルにエクスポートできることを理解しました。

C.py

obj = None 
def setObj(object): 
    obj = object 

def dependency(): 
    #use obj now 
    pass  

setObj(objが)今A.pyから呼び出すことができます!この問題を回避しようとする

+0

通常、循環依存関係はプロジェクトの構造が悪いことを示します。他のファイルに依存するコードを抽出します。これは多くのものを動かす必要があるかもしれません。 – Carcigenicate

+0

構造を教えてもらえますか? @カルシゲネイト? –

答えて

0

アプリの設定に関する問題は、フラスコのconfig dictionaryで処理できます。

モジュールC.pyでは、フラスコのcurrent_app objectを使用してアプリケーション構成にアクセスできます。 A.pyがあなたのメインのアプリケーションファイルである場合

# A.py 
from flask import Flask 
app = Flask(__name__ 
app.config['MY_CONFIG_KEY'] = 'something' 

は、その後、あなたは次のようにC.pyでアプリの設定にアクセスすることができます。

# C.py 
from flask import current_app 

def dependency(): 
    v = current_app.config['MY_CONFIG_KEY'] 

注意すべき重要な点である円形を解決するためのflasky方法アプリケーションファクトリとBlueprintsを使用することです。

0

一つの方法は、すべての円形の輸入の例外をキャッチすることです:

>>> try: 
>>> from mylib import myclass 
>>> except: 
>>> pass 
>>> try: 
>>>  from mylib2 import myclass2 
>>> except: 
>>>  pass 

私はまた、あなたがそれらをmeedとき、packgesをインポートしている好きではない別の解決策、。結果として、あなたはそれを必要とする関数内の輸入を行う必要があります。

>>> def func1(): 
>>>  from mylib import myclass 
>>>  c = myclass() 
>>>  .... 
>>> 
>>> def func2(): 
>>>  from mylib2 import myclass2 
>>>  ... 

別の可能sulutionアプリのオブジェクトクレタした後、すべての設計図の依存関係をインポートすることです。つまり、依存関係のインポートが遅れたため、オブジェクト "app"を安全にインポートできます。あなたのmain.py(またはメインファイル)で

:あなたのviews.pyで

>>> from flask import Flask 
>>> 
>>> app = Flask() 
>>> 
>>> from . import views # safe to import "app" from views.py now! 
>>> 
>>> a = 3 # this generates circular dependency error from views.py. it hasn't been creted yet!! 

>>> from .main import app # safe to import "app". 
>>> 
>>> app.route("/") 
>>> def hello_world(): 
>>>  ... 

あなたはviews.pyがメイン呼び出した時点で、鑑賞することができたよう。 py "app"オブジェクトの場合、既に作成されています。

しかし、最善の解決策は、アプリを再設計することです。別の言い方をすれば、アプリでこの問題が見つかった場合は、それを正しく設計しておらず、別のファイルシステムスキーマ(または別のアーキテクチャ)が必要であるという明確な兆候です。

また、次のリンクで利用可能な工場のデザインパターンを参照することができます。

http://flask.pocoo.org/docs/0.12/patterns/appfactories/

は個人的に、私は工場を使用して、私は今のところすべての問題を持っていませんでした。

+0

ありがとうございました! –