Python 包含成员函数的循环依赖
Python circular dependency with the inclusion of member functions
当我尝试将现有函数作为成员函数合并到 class 中时,问题就出现了。我有一个类似于这样的设置:
类:
base(object)
primitive(base)
square(primitive)
union(primitive)
我有一个名为 union
的函数,用户将其称为 returns 一个 union
原始对象。
obj1 = square()
obj2 = square()
obj3 = union(obj1, obj2) #this is the union function which returns a union primitive
我希望用户也能做到这一点
obj3 = obj1.union(obj2)
这就是问题所在。 primitive
class 需要导入 union
函数,进而导入 union
class,进而导入 primitive
class,而我运行陷入循环依赖错误。有没有一种聪明的方法来重构代码或更改导入语句以允许它工作?
编辑:
为清楚起见,代码的结构如下:
operations/union.py(函数)
from objects import union as _union #the union class
def union(obj1, obj2): #the union function
#CODE
return _union(args)
objects/union.py (class)
from objects import primitive
class union(primitive):
#CODE
objects/primitive.py
from operations import union #the function
class primitive(base):
#CODE
def union(self, obj2):
return union(self, obj2)
有一个叫做union
的class,它是一个包含联合输入对象信息的对象。用户不与之交互。然后是用户可以调用的 union
函数,其中 returns 一个 union
对象。我希望 primitive
class 包含一个名为 union
的成员函数,它使用我已经编写的 union
函数。问题是 union
函数 returns 一个继承自 primitive
class 的 union
对象。这会导致循环依赖问题。我可以删除 union
成员函数,但用户不能这样做
obj3 = obj1.union(obj2)
听起来您将 primitive
和 square
定义在单独的 modules/files 中给自己带来了很多麻烦。如果您在同一个模块中定义它们,我怀疑您会遇到任何麻烦。例如,以下工作正常:
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
需要在模块范围内定义 class ,因此保持 union.py
as-is:
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
class 已经存在。因此在 class 主体之后导入。
我建议将 union
设为 Union
的 @classmethod
,以便您可以将其正确用作替代构造函数。此外,使用 Python 约定,在 CamelCase 中编写 class 名称可以减少命名的混乱。
当我尝试将现有函数作为成员函数合并到 class 中时,问题就出现了。我有一个类似于这样的设置:
类:
base(object)
primitive(base)
square(primitive)
union(primitive)
我有一个名为 union
的函数,用户将其称为 returns 一个 union
原始对象。
obj1 = square()
obj2 = square()
obj3 = union(obj1, obj2) #this is the union function which returns a union primitive
我希望用户也能做到这一点
obj3 = obj1.union(obj2)
这就是问题所在。 primitive
class 需要导入 union
函数,进而导入 union
class,进而导入 primitive
class,而我运行陷入循环依赖错误。有没有一种聪明的方法来重构代码或更改导入语句以允许它工作?
编辑:
为清楚起见,代码的结构如下:
operations/union.py(函数)
from objects import union as _union #the union class
def union(obj1, obj2): #the union function
#CODE
return _union(args)
objects/union.py (class)
from objects import primitive
class union(primitive):
#CODE
objects/primitive.py
from operations import union #the function
class primitive(base):
#CODE
def union(self, obj2):
return union(self, obj2)
有一个叫做union
的class,它是一个包含联合输入对象信息的对象。用户不与之交互。然后是用户可以调用的 union
函数,其中 returns 一个 union
对象。我希望 primitive
class 包含一个名为 union
的成员函数,它使用我已经编写的 union
函数。问题是 union
函数 returns 一个继承自 primitive
class 的 union
对象。这会导致循环依赖问题。我可以删除 union
成员函数,但用户不能这样做
obj3 = obj1.union(obj2)
听起来您将 primitive
和 square
定义在单独的 modules/files 中给自己带来了很多麻烦。如果您在同一个模块中定义它们,我怀疑您会遇到任何麻烦。例如,以下工作正常:
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
需要在模块范围内定义 class ,因此保持 union.py
as-is:
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
class 已经存在。因此在 class 主体之后导入。
我建议将 union
设为 Union
的 @classmethod
,以便您可以将其正确用作替代构造函数。此外,使用 Python 约定,在 CamelCase 中编写 class 名称可以减少命名的混乱。