【问题标题】:Why does this non-circular inheritance in Python trigger an import error?为什么 Python 中的这种非循环继承会触发导入错误?
【发布时间】:2021-06-21 14:15:09
【问题描述】:

编辑: 原来继承是循环的。继续阅读!

我正在使用 Python 3.6。我试图生成一个最小的代码示例来调试我在代码项目中遇到的导入错误,这是由我设置继承的方式引起的。我怀疑我做错了什么,但我不明白我违反了什么编码原则。

文件结构如下:

temp
 |-- __init__.py
 |-- superclass_file.py
 |-- subclass_file.py 
 |-- tests
      |-- __init__.py
      |-- test_subclass_file.py

这些是 Python 脚本的内容:

# temp/__init__.py

from .subclass_file import *
from .superclass_file import *
# temp/superclass_file.py

class Parent:

    def __init__(self):
        print('I exist.')
# temp/subclass_file.py

from temp import Parent


class Child(Parent):

    def __init__(self):
        super().__init__()
        print('And I exist because of it.')

    def print_something(self):
        print('Yes, I\'m here.')


if __name__ == '__main__':
    Child()
# temp/tests/__init__.py

from .test_subclass_file import *
# temp/tests/test_subclass_file.py

from unittest import TestCase

from temp import Child


class TestChild(TestCase):

    def check_inheritance(self):
        c = Child()

        c.print_something()

当我运行check_inheritance() 时,它失败并抛出此错误:

/usr/local/bin/python3.6 ~/temp/subclass_file.py
Traceback (most recent call last):
  File "~/temp/subclass_file.py", line 1, in <module>
    from temp import Parent
  File "~/temp/__init__.py", line 1, in <module>
    from .subclass_file import *
  File "~/temp/subclass_file.py", line 1, in <module>
    from temp import Parent
ImportError: cannot import name 'Parent'

当我在subclass_file.py 中运行main() 方法时,我遇到了类似的错误。

然而,当我将subclass_file.py 中Parent 的导入从from temp import Parent 更改为from temp.superclass_file import Parent 时,错误完全消失了。

为什么会这样?在继承的情况下,为什么我不能使用我在其他任何地方使用的相同导入签名——from temp import Parent?我是否错误地配置了__init__.py 文件?

【问题讨论】:

  • 它是圆形的。 temp.subclass_file 导入temp,它必须导入.subclass_file,它必须导入temp,它导入.subclass_file,它导入....
  • 我天真地认为 Python 解释器会清除导入。谢谢,@chepner。我现在的问题是,从代码清洁度的角度来看,哪种方式更好。我更喜欢像from x import y 这样的导入而不是from z.x import y。不过,从长远来看,不确定哪个更好。
  • 我会直接从superclass_file 导入Parent,而不是通过“公共”接口。
  • 为了安全起见,我想我会这样做。我是否应该像在__init__.py 中那样继续公开Parent 和Child?

标签: python class inheritance module importerror


【解决方案1】:

现在您在 superclass_file.py 之前导入 subclass_file.py。

所以当你尝试做from temp import Parent时,因为subclass_file.py是之前导入的,它不知道Parent是什么。此外,您可能会创建循环导入问题。

最好的方法应该是使用from temp.superclass_file import Parent

如果你真的想/需要使用其他方式,那么你必须在subclass_file.py之前导入superclass_file.py

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-30
    • 2020-11-05
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多