不同模块中的继承

2024-09-30 18:23:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个父类和一个子类,每一个都在各自独立的文件中。如果这两个类在一个文件中,我的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: cannot import name 'MainWin' from 'main_win' (/home/basil/scratch/trash/pythonInheritance/p03/main_win.py)

编辑: 有一些有效的评论质疑我的类结构:我需要继承吗?我可以添加一个超类,上面的两个类都可以从中继承吗?这些都是很好的评论,我会仔细考虑的。当然,MWE对你的体重没有帮助 在回答这些问题时。现在,让我们假设类结构不会改变。那么这个问题怎么解决呢?通过将两个模块合并为一个模块,还是有其他方法?你知道吗


Tags: 文件frompytestimportenvbinmain
2条回答

你有一个循环导入。main_win.py导入sub_win.py导入main_win.py。。。你知道吗

要解决这个问题并保持代码不变,技术上可以将from sub_win import SubWin移动到MainWin.click()。这绝对不是我的建议,不过,你可能应该回到设计和重新考虑这种方法,无论你试图实现什么。你知道吗

你的问题是,你有一个循环进口情况。main_win模块导入sub_win,并且sub_win尝试将main_win导入回,但它无法正常工作,因为MainWin类在sub_win模块尝试导入时还不存在。你知道吗

有几种可能的解决办法。你知道吗

通常,最好的解决方案是消除两个类之间的循环依赖关系。循环导入是不被禁止的,但对它们的需求往往表明设计的草率。还有很多方法可以修复依赖关系。在示例代码中,根本不需要SubWinMainWin继承,因此可以直接删除继承。如果他们确实需要共享一些共同的代码或信息,也许他们都应该从一个共同的祖先那里继承它(例如Window),共享的东西可以去那里。另一个选项将使这两个类不相关,但是MainWinSubWin需要的信息传递给它的构造函数(例如options = SubWin(some_data))。你知道吗

另一种选择可能是将sub_win的导入推迟到main_win命名空间中存在MainWin之后。您可以通过将from sub_win import SubWin语句移到代码中较低的位置来实现这一点。它可以保持在模块的顶层,在MainWin的定义之下,也可以放在click方法的内部,在那里使用它(因此它将是函数中的局部变量,而不是全局变量)。你知道吗

最后一个想法是将类放在同一个模块中,这样就根本不需要import语句。如果您的两个类像您当前的设计建议的那样紧密耦合,那么绝对没有理由将它们分离成单独的模块。Python与其他一些编程语言(如Java)非常不同,在Java中,默认情况下每个类都有自己的源文件。Python项目通常具有大型模块,其中包含许多类和全局函数。你只需要把你的模块分成几个部分,如果它们太大了,你会发现你经常使用它们的部分代码,而不需要其他部分。你知道吗

相关问题 更多 >