我有两个文件node.py
和path.py
,分别定义了两个类Node
和Path
。
到目前为止,Path
的定义引用了Node
对象,因此我已经完成了
from node.py import *
在path.py
文件中。
但是,截至今天,我为Node
创建了一个引用Path
对象的新方法。
我在尝试导入path.py
时遇到了问题:我尝试过,当程序运行并调用使用Path
的{{1}}方法时,异常上升{{1}没有被定义。
我该怎么办?
答案 0 :(得分:96)
Importing Python Modules 是一篇很棒的文章,解释了Python中的循环导入。
解决此问题的最简单方法是将路径导入移动到节点模块的末尾。
答案 1 :(得分:20)
另一种方法是导入两个模块中的一个仅在函数中导入另一个模块。当然,如果您只需要一个或少量功能,这种方法效果最好:
# in node.py
from path import Path
class Node
...
# in path.py
class Path
def method_needs_node():
from node import Node
n = Node()
...
答案 2 :(得分:0)
我更喜欢通过在另一个依赖类的构造函数中声明一个依赖来打破循环依赖。在我看来,这可以使代码保持整洁,并可以轻松访问需要依赖项的所有方法。
因此,在我的情况下,我有一个相互依赖的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)
答案 3 :(得分:0)
您可能无需为了将Path
和node.py
彼此使用而在Path
中导入Node
。
# in __init__.py (The order of imports should not matter.)
from .node import Node
from .path import Path
# in path.py
from . import Node
class Path
...
def return_something_pathy(self):
...
# in node.py
class Node
def __init__(self, path):
self.path = path
...
def a_node_method():
print(self.path.return_something_pathy())
要明确说明Node
正在使用Path
,请添加类型提示。从PEP 563开始,从Python 3.7开始有一项功能可以支持类型注释中的前向引用。
# in node.py (Now with type hinting.)
from __future__ import annotations
class Node
def __init__(self, path: Path):
self.path = path
...
def a_node_method():
print(self.path.return_something_pathy())
I came across a Yet another solution to dig you out of a circular import hole in Python 是一篇很棒的博客文章,教我了这一点。