如何导入包含 类 且循环依赖的模块?

How to import modules containing classes with circular dependency?

假设我有以下基础并且child

class Base:

    def __new__(cls, *args):
        if cls is Base:
            if len(args) < 2:
                return Child1.__new__(Child1, *args)

            return Child2.__new__(Child2, *args)

        return super().__new__(cls)

    def __init__(self, arg):
        self.common_arg = arg


class Child1(Base):
    def __init__(self, arg0=None):
        super().__init__(arg0)



class Child2(Base):
    def __init__(self, arg0, arg1, *args):
        super().__init__(arg0 + arg1)

        self.args = list(args).copy()

类 之间显然存在循环依赖,但是,只要所有 类 都定义在同一个模块中,这不会导致任何问题。

现在,我应该如何将它们分成三个模块(在同一个包中)?

我拆分成三个文件:

package/
    __init__.py
    base.py
    ch1.py
    ch2.py

内容如下:

# base.py ############################################################

from . import ch1, ch2

class Base:

    def __new__(cls, *args):
        if cls is Base:
            if len(args) < 2:
                return ch1.Child1.__new__(ch1.Child1, *args)

            return ch2.Child2.__new__(ch2.Child2, *args)

        return super().__new__(cls)

    def __init__(self, arg):
        self.common_arg = arg


# ch1.py ############################################################
from . import base

class Child1(base.Base):
    def __init__(self, arg0=None):
        super().__init__(arg0)

# ch2.py ############################################################
from . import base


class Child2(base.Base):
    def __init__(self, arg0, arg1, *args):
        super().__init__(arg0 + arg1)
        self.args = list(args).copy()   

按照建议 here 但它不起作用。

import package.ch1

加注

AttributeError: module 'package.base' has no attribute 'Base'

让您的用户调用工厂函数:

def make_base(*args):
    if len(args) < 2:
        return Child1(*args)

    return Child2(*args)


class Base:
    def __init__(self, arg):
        self.common_arg = arg


class Child1(Base):
    pass        # Child1 automatically inherits Base.__init__()


class Child2(Base):
    def __init__(self, arg0, arg1, *args):
        super().__init__(arg0 + arg1)

        self.args = list(args).copy()

现在以上代码的每一部分都可以拆分成自己的文件。