web-dev-qa-db-ja.com

Pythonの循環依存関係

2つのファイル、node.pyおよびpath.pyは、それぞれNodePathの2つのクラスを定義します。

今日まで、Pathの定義はNodeオブジェクトを参照していたため、

from node.py import *

の中に path.pyファイル。

ただし、今日の時点で、Nodeオブジェクトを参照するPathの新しいメソッドを作成しました。

インポートしようとしたときに問題が発生しましたpath.py:試してみましたが、プログラムを実行してPathを使用するNodeメソッドを呼び出すと、Nodeが定義されていないという例外が発生しました。

私は何をしますか?

59
Ram Rachum

Importing Python Modulesは、Pythonでの循環インポートを説明する素晴らしい記事です。

これを修正する最も簡単な方法は、パスインポートをノードモジュールの最後に移動することです。

103
Nadia Alramli

もう1つのアプローチは、2つのモジュールの1つを、他のモジュールで必要な関数にのみインポートすることです。確かに、これは1つまたは少数の機能でのみ必要な場合に最適です。

# in node.py 
from path import Path
class Node 
    ...

# in path.py
class Path
  def method_needs_node(): 
    from node import Node
    n = Node()
    ...
22
mircealungu

他の依存クラスのコンストラクターで依存関係の1つを宣言することにより、循環依存関係を解除することを好みます。私の見解では、これはコードをよりきれいに保ち、依存関係を必要とするすべてのメソッドに簡単にアクセスできるようにします。

したがって、私の場合、CustomerServiceとUserServiceが相互に依存しています。次のように循環依存関係を解除します。

class UserService:

    def __init__(self):
        # Declared in constructor to avoid circular dependency
        from server.portal.services.admin.customer_service import CustomerService
        self.customer_service = CustomerService()

    def create_user(self, customer_id: int) -> User:
        # Now easy to access the dependency from any method
        customer = self.customer_service.get_by_id(customer_id)
1
Iain Hunter