9

ユーザー.py:

from story import Story

class User:
    ...
    def get_stories(self):
        story_ids = [select from database]
        return [Story.get_by_id(id) for id in story_ids]

ストーリー.py

from user import User

class Story:
    ...
    def __init__(self, id, user_id, content):
        self.id = id
        self.user = User.get_by_id(user_id)
        self.content = content

ご覧のとおり、このプログラムには循環インポートがあり、ImportError. このエラーを防ぐために、メソッド定義で import ステートメントを移動できることを学びました。しかし、私はまだ知りたいのですが、この場合に循環インポートを削除する方法はありますか、それとも(良い設計のために)必要ですか?

4

4 に答える 4

1

この場合の最も明白な解決策はUserStoryコンストラクターUseruser_id. これは、より効率的な設計にもつながります。たとえば、ユーザーが多くのストーリーを持っている場合、同じオブジェクトをそれらすべてのコンストラクターに与えることができます。

それ以外は、モジュール全体 (つまり、メンバーの代わりに ) のインポートがstory機能userするはずです。最初にインポートされたモジュールは、2 番目のインポート時に空に見えます。ただし、これらのモジュールの内容はグローバル スコープでは使用されないため、問題ではありません。

これは、メソッド内でインポートするよりもわずかに優れています。story.Storyメソッド内でのインポートは、メソッド呼び出しごとに実行する必要があるため、モジュール グローバル ルックアップ ( ) よりもかなりのオーバーヘッドがあります。単純なケースでは、オーバーヘッドは少なくとも 30 倍になるようです。

于 2013-11-15T18:15:39.183 に答える
1

循環性を軽減する別の方法は、インポート スタイルを変更することです。に変更from story import Storyimport story、クラスを として参照しstory.Storyます。メソッド内のクラスのみを参照するため、メソッドが呼び出されるまでクラスにアクセスする必要はありません。メソッドが呼び出されるまでに、インポートは正常に完了します。(どちらが最初にインポートされるかに応じて、どちらかまたは両方のモジュールでこの変更を行う必要がある場合があります。)

ただし、デザインはやや奇妙に見えます。あなたの設計は、UserStoryクラスが非常に密接に結合されているようなものです。どちらも他方なしでは使用できません。このような場合、通常は両方を同じモジュールに入れる方が理にかなっています。

于 2013-11-15T07:53:02.893 に答える