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

2024-07-03 08:22:10 发布

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

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

课程:

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语句以使其工作?你知道吗

编辑:

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

操作/联合.py(功能)

from objects import union as _union #the union class
def union(obj1, obj2): #the union function
    #CODE
    return _union(args)

对象/联合.py(班级)

from objects import primitive
class union(primitive):
    #CODE

对象/原始.py

from operations import union #the function
class primitive(base):
    #CODE
    def union(self, obj2):
        return union(self, obj2)

有一个名为union的类,它是一个包含联合输入对象信息的对象。用户不与此交互。然后是用户可以调用的union函数,它返回一个union对象。我希望primitive类包含一个名为union的成员函数,它使用我已经编写的union函数。问题是union函数返回从primitive类继承的union对象。这会导致循环依赖性问题。我可以删除union成员函数,但是用户不能这样做

obj3 = obj1.union(obj2)

Tags: the对象函数用户pyimportbasefunction
2条回答

听起来你在不同的模块/文件中定义了primitivesquare,给自己带来了很多麻烦。如果你在同一个模块中定义它们,我怀疑你会有任何麻烦。例如,以下操作很好:

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循环导入的good resource。你知道吗

如果您不依赖模块级导入的任何内容,可以将导入放在文件的末尾。在union的情况下,需要Primitive来定义模块作用域中的类,因此保持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。如果您首先导入objects.primitive,它将尝试导入objects.union,这要求Primitive类已经存在。因此在类主体之后导入。你知道吗

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

相关问题 更多 >