包含成员函数的Python循环依赖关系

包含成员函数的Python循环依赖关系,python,circular-dependency,Python,Circular Dependency,当我尝试将一个现有函数作为成员函数合并到一个类中时,就会出现这个问题。我的设置与此类似: 课程: base(object) primitive(base) square(primitive) union(primitive) 我有一个名为union的函数,用户调用该函数返回一个union原语对象 obj1 = square() obj2 = square() obj3 = union(obj1, obj2) #this is the union func

当我尝试将一个现有函数作为成员函数合并到一个类中时,就会出现这个问题。我的设置与此类似:

课程:

base(object)
    primitive(base)
        square(primitive)
        union(primitive)
我有一个名为
union
的函数,用户调用该函数返回一个
union
原语对象

obj1 = square()
obj2 = square()
obj3 = union(obj1, obj2) #this is the union function which returns a union primitive
我希望用户也能够做到这一点

obj3 = obj1.union(obj2)
这就是问题所在。
primitive
类需要导入
union
函数,该函数依次导入
union
类,该类依次导入
primitive
类,我遇到了一个循环依赖错误。有没有一种聪明的方法来重构代码或修改import语句以使其工作

编辑:

为了清楚起见,代码的结构如下:

操作/union.py(函数)

对象/union.py(类)

对象/primitive.py

from operations import union #the function
class primitive(base):
    #CODE
    def union(self, obj2):
        return union(self, obj2)
有一个名为
union
的类,它是一个包含有关联合输入对象的信息的对象。用户不与此进行交互。然后是用户可以调用的
union
函数,它返回一个
union
对象。我希望
原语
类包含一个名为
union
的成员函数,该函数使用我已经编写的
union
函数。问题是
union
函数返回一个从
原语
类继承的
union
对象。这会导致循环依赖性问题。我可以删除
union
成员函数,但用户不能这样做

obj3 = obj1.union(obj2)

听起来您在单独的模块/文件中定义了
primitive
square
,给自己带来了很多麻烦。如果您在同一模块中定义它们,我怀疑您会遇到任何问题。例如,以下方法可以很好地工作:

class Primitive:
    pass

class Square(Primitive):
    def union(self, other):
        return Union(self, other)

class Union(Primitive):
    def __init__(self, *members):
        self.members = members

obj1 = Square()
obj2 = Square()
obj3 = obj1.union(obj2)

print(type(obj3))
print(obj3.members)
但是,如果您坚持将类放在不同的文件中,您可以这样做:

primitive.py:

    class Primitive:
        pass

square.py:

    from .primitive import Primitive

    class Square(Primitive):
        def union(self, other):
            from .union import Union
            return Union(self, other)

union.py:

    from .primitive import Primitive

    class Union(Primitive):
        def __init__(self, *members):
            self.members = members

test.py:

    from .square import Square

    obj1 = Square()
    obj2 = Square()
    obj3 = obj1.union(obj2)

    print(type(obj3))
    print(obj3.members)
关键点是将
from.union import union
语句移动到
union()
方法中,直到需要时才会调用它


这里有一个关于Python循环导入的示例。

听起来您在单独的模块/文件中定义了
原语
正方形
,给自己带来了很多麻烦。如果您在同一模块中定义它们,我怀疑您会遇到任何问题。例如,以下方法可以很好地工作:

class Primitive:
    pass

class Square(Primitive):
    def union(self, other):
        return Union(self, other)

class Union(Primitive):
    def __init__(self, *members):
        self.members = members

obj1 = Square()
obj2 = Square()
obj3 = obj1.union(obj2)

print(type(obj3))
print(obj3.members)
但是,如果您坚持将类放在不同的文件中,您可以这样做:

primitive.py:

    class Primitive:
        pass

square.py:

    from .primitive import Primitive

    class Square(Primitive):
        def union(self, other):
            from .union import Union
            return Union(self, other)

union.py:

    from .primitive import Primitive

    class Union(Primitive):
        def __init__(self, *members):
            self.members = members

test.py:

    from .square import Square

    obj1 = Square()
    obj2 = Square()
    obj3 = obj1.union(obj2)

    print(type(obj3))
    print(obj3.members)
关键点是将
from.union import union
语句移动到
union()
方法中,直到需要时才会调用它


这里有一个关于Python循环导入的示例。

如果您不依赖模块级导入的任何内容,可以将导入放在文件的末尾。在
union
的情况下,需要
原语来定义模块范围内的类,因此保持
union.py
不变:

from objects.primitive import Primitive
class Union(Primitive):
    @classmethod
    def union(cls, a, b):
        return Union(a, b)
但是
primitive
只需要在一个方法中使用
Union
,而不需要在模块范围内创建任何内容,因此您所需要的只是在调用该方法时导入的模块存在。这意味着您可以这样做:

class Primitive(Base):
    #CODE
    def union(self, obj2):
        return union.Union.union(self, obj2)

from objects import union
您需要将导入放在末尾的原因是为了确保无论先导入哪个模块,它都能工作。如果导入
objects.union
,它将在到达模块主体之前正确导入
objects.primitive
。如果首先导入
对象.primitive
,它将尝试导入
对象.union
,这要求
primitive
类已经存在。因此,在类主体之后导入


我建议将
union
作为
union
@classmethod
,这样您就可以正确地将其用作替代构造函数。另外,使用在CamelCase中编写类名的Python约定可以大大减少命名的混乱。

如果您不依赖模块级导入的任何内容,可以将导入放在文件的末尾。在
union
的情况下,需要
原语来定义模块范围内的类,因此保持
union.py
不变:

from objects.primitive import Primitive
class Union(Primitive):
    @classmethod
    def union(cls, a, b):
        return Union(a, b)
但是
primitive
只需要在一个方法中使用
Union
,而不需要在模块范围内创建任何内容,因此您所需要的只是在调用该方法时导入的模块存在。这意味着您可以这样做:

class Primitive(Base):
    #CODE
    def union(self, obj2):
        return union.Union.union(self, obj2)

from objects import union
您需要将导入放在末尾的原因是为了确保无论先导入哪个模块,它都能工作。如果导入
objects.union
,它将在到达模块主体之前正确导入
objects.primitive
。如果首先导入
对象.primitive
,它将尝试导入
对象.union
,这要求
primitive
类已经存在。因此,在类主体之后导入


我建议将
union
作为
union
@classmethod
,这样您就可以正确地将其用作替代构造函数。另外,使用在CamelCase中编写类名的Python约定可以大大减少命名的混乱。

您能提供一个简单的示例吗?我看不懂你的图表。并集是一个类还是一个函数?到底发生了什么?在任何情况下,只要把这些东西放在同一个模块中,你的循环依赖关系就可以解决。让我知道如果编辑清除了这些东西,你为什么不把所有的类放在同一个模块中呢?或者将
union
类和
union
函数放在同一个模块中?能否提供一个?我看不懂你的图表。并集是一个类还是一个函数?到底发生了什么?在任何情况下,只要把这些东西放在同一个模块中,你的循环依赖关系就可以得到解决