0

私のプロジェクトではinteraction、システム機能にアクセスするための「インターフェース」を含むモジュールを使用しています。たとえば、2 つのモジュールが異なるインターフェイスを実装しており、そのうちの 1 つは他のインターフェイスに依存しています。

module1.py :

value = 5

def init():
    pass

def provide_int():
    global value
    return value

module2.py :

def init():
    import interaction
    global value
    value = str(interaction.int_provider.provide_int())

def provide_string():
    global value
    return value

だから私はそれを同じように使いたい:

相互作用.py :

from importlib import import_module

globals()['int_provider'] = import_module('module1')
globals()['int_provider'].init()
globals()['str_provider'] = import_module('module2')
globals()['str_provider'].init()

したがって、初期化中にmodule2(init関数を呼び出す)、循環インポートのためにImportErrorが発生します。この例はもちろん合成ですが、一般的な状態は同じです。

2 つの質問があります: 1.インターフェイスをプロキシする
ように「グローバル」モジュールを使用するのは正しい方法ですか? 2. この循環インポートを無効にするにはどうすればよいですか?interaction.py

4

2 に答える 2

0

この循環インポートを無効にするにはどうすればよいですか?

django.utils.functional.SimpleLazyObjectのようなものを使用して、遅延作成されたプロバイダーを使用できます。このようにして、プロバイダーの属性がアクセスされた瞬間にプロバイダーを初期化します。渡された関数は毎回再評価されるため、結果を覚えておく必要がありますSimpleLazyObject

使用法:

def init_str_provider():
    if not hasattr(init_str_provider, 'provider'):
        init_str_provider.provider = import_module('module2')
        init_str_provider.provider.init()
    return init_str_provider.provider

str_provider = SimpleLazyObject(init_str_provider)

interaction.pyインターフェイスをプロキシするように「グローバル」モジュールを使用するのは正しい方法ですか?

インターフェイスを使用してそのような構造を作成する場合は、次のようにします。

  • のプロバイダー クラス登録メソッドinterfaces.py
  • クラスを使用してプロバイダーを表します (継承によりインターフェースがより簡単になります!)。
  • 遅延プロバイダー初期化を許可するget_provider(name)関数を提供します。interfaces.py

このような分離により、個別のプロバイダーのテストとモック化がはるかに簡単になり、カスタマイズのためのスペースが増えます。また、あるプロバイダの動作を別のプロバイダ内に拡張する必要がある場合、クラス オブジェクトはモジュール レベルではなく、その内部に状態を格納します。このようにして、子プロバイダーがスタンドアロンの基本プロバイダーの内部をいじることを心配することなく、実際に他のプロバイダーから継承することができます。

于 2013-09-27T12:05:48.800 に答える