Круговая зависимость в Python - PullRequest
55 голосов
/ 22 мая 2009

У меня есть два файла, node.py и path.py, которые определяют два класса, Node и Path соответственно.

До сегодняшнего дня определение для Path ссылалось на объект Node, и поэтому я сделал

from node.py import *

в файле path.py.

Однако на сегодняшний день я создал новый метод для Node, который ссылается на объект Path.

У меня возникли проблемы при попытке импортировать path.py: я попробовал это сделать, и когда программа запустилась и вызвала метод Path, использующий Node, возникло исключение: Node не определено.

Что мне делать?

Ответы [ 3 ]

96 голосов
/ 22 мая 2009

Импорт модулей Python - отличная статья, объясняющая циклический импорт в Python.

Самый простой способ исправить это - перенести путь импорта в конец модуля узла.

20 голосов
/ 14 июня 2016

Еще один подход - импортировать один из двух модулей только в функцию , где он вам нужен в другом. Конечно, это работает лучше всего, если вам нужно только одно или небольшое количество функций:

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

# in path.py
class Path
  def method_needs_node(): 
    from node import Node
    n = Node()
    ...
0 голосов
/ 27 февраля 2019

Я предпочитаю прерывать циклическую зависимость, объявив одну из зависимостей в конструкторе другого зависимого класса. На мой взгляд, это делает код более аккуратным и обеспечивает легкий доступ ко всем методам, которым требуется зависимость.

Так что в моем случае у меня есть 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)
...