我有一个父类和一个子类,每个类都在各自单独的文件中。如果这两个类在一个文件中,则我的MWE有效。如果将它们分别分成各自的文件,我将不知道如何相互导入。这是MWE:
cat test.py
#!/usr/bin/env python3
from main_win import MainWin
test = MainWin()
test.click()
cat main_win.py
#!/usr/bin/env python3
from sub_win import SubWin
class MainWin:
def __init__(self):
print('Created main window')
def click(self):
options = SubWin()
cat sub_win.py
#!/usr/bin/env python3
from main_win import MainWin
class SubWin(MainWin):
def __init__(self):
print('Created sub window')
如果我执行test.py
并使用如上定义的循环导入,则会出现以下错误:
ImportError:无法从“ main_win”(/ home / basil / scratch / trash / pythonInheritance / p03 / main_win.py)导入名称“ MainWin”
编辑: 有一些有效的评论质疑我的课程结构:我需要继承吗?我可以添加一个超级类,上面的两个类都可以从中继承吗?这些都是很好的评论,我会仔细考虑的。当然,MWE对您而言无济于事 回答这些问题。现在,让我们假设不更改类结构。那么该如何解决呢?通过将两个模块合并为一个模块,还是有另一种方法?
答案 0 :(得分:1)
您有一个循环进口。 main_win.py
导入sub_win.py
,其中导入main_win.py
...
要解决此问题并使代码保持原样,您可以从技术上将from sub_win import SubWin
移到MainWin.click()
中。不过,这绝对不是我建议的内容,您可能应该重新设计并重新考虑这种方法,以解决您想要达到的目标。
答案 1 :(得分:0)
您的问题是您有一个循环进口情况。 main_win
模块将导入sub_win
,而sub_win
会尝试将main_win
导入回来,但由于MainWin
类尚不存在而无法正常工作sub_win
模块尝试导入时。
有一些可能的解决方案。
通常最好的解决方案是摆脱两个类之间的循环依赖。禁止循环进口,但对它们的需求通常表明设计草率。也有很多方法可以解决依赖关系。在示例代码中,您根本不需要SubWin
从MainWin
继承,因此您可以删除继承。如果他们确实需要共享一些通用代码或信息,也许他们俩都应该从一个共享祖先(例如Window
)那里继承它们。另一种选择是使这两个类不相关,但是让MainWin
将信息SubWin
所需的信息传递给其构造函数(例如options = SubWin(some_data)
)。
另一种选择是将sub_win
的导入推迟到MainWin
名称空间中存在main_win
之后。您可以通过将from sub_win import SubWin
语句移到代码中更下方的位置来实现。它可以保留在模块MainWin
定义之下的顶层,也可以放在使用它的click
方法内部(因此它将是功能,而不是全局)。
最后一个想法是将您的类放在同一模块中,因此您根本不需要import语句。如果您的两个类如您当前设计所建议的那样紧密耦合,那么绝对没有理由将它们分成单独的模块。 Python与其他一些编程语言(例如Java)有很大的不同,在默认语言中,每个类都有自己的源文件。 Python项目通常具有包含许多类和全局函数的大型模块。如果模块太大,只需要定期拆分即可,只需定期使用部分代码即可,而无需其他部分。