我有一个类Model
,当然有一些方法。除此之外,我有一个类,ModelList
其子类表示 .q 子类的实例列表Model
。除其他外,ModelList
子类的用途是提供批量操作,这不同于仅将操作委托给ModelList
. 因此,ModelList
子类的目的是“向量化”相应Model
类的方法。
我还在ModelList
某些地方使用了,我希望允许子类Model
或ModelList
允许作为传递给函数的参数。
ModelList
正在了解(并检查)其任何元素将被接受的类型。为了让子类ModelList
知道其对应的Model
子类,我将其定义为子类element_type
上的类变量ModelList
。
每个ModelList
子类都与一个子类紧密耦合Model
:一个ModelList
类属于一个Model
类。这就是为什么我将ModelList
子类作为其各自Model
类的内部类。我的问题来了:因为在每个类的初始化过程中ModelList
需要知道Model
和Model
需要知道ModelList
两者,所以我的类之间存在循环依赖关系。
我将代码简化为最小示例,以使我的设计更易于理解:
class Model(ABC):
pass
class ModelList(list):
@classmethod
def __init__(self, elements=None):
elements = list() if not elements else elements
for value in elements:
self._check_type(value)
list.__init__(self, elements)
def _check_type(self, val):
if not isinstance(val, self.__class__.element_type):
raise TypeError(
f"{self.__class__} accepts only instances of {self.__class__.element_type} as elements. `{val}` is not!")
以下导致错误free variable 'SomeModel' referenced before assignment in enclosing scope
:
class SomeModel(Model):
class List(ModelList):
element_type = SomeModel # this causes the Error
我知道我可以通过解耦这两个类来摆脱循环依赖。但我想无论是Model
类知道其对应的ModelList
类,也是我想要的ModelList
类以了解它的Model
类。每个Model
班级都应该有一个并且只有一个List
附加到它。
我知道我可以通过Model
像这样“monkeypatching”我的子类来规避依赖:
class SomeModel(Model):
pass
class SomeModelList(ModelList):
element_type = SomeModel
SomeModel.List = SomeModelList
对我来说,感觉这是设计缺陷的标志。我说不出为什么,但感觉“错了”。
element_type
在稍后Model
定义相应的子类时评估?如果你想让 SomeModelList 表现得像一个泛型,你应该提供元素类作为构造函数的参数并将它分配给 self.element_type 那里。
class ModelList(list):
def __init__(self, model, elements=None):
self.element_Type = model
elements = list() if not elements else elements
for value in elements:
self._check_type(value)
list.__init__(self, elements)
def _check_type(self, val):
if not isinstance(val, self.element_type):
raise TypeError(
f"{self.__class__} accepts only instances of {self.element_type} as elements. `{val}` is not!")
# usage
modelList = ModelList(SomeModel,[instance1,instance2,instance3])
然后,您可以通过向 Model 基类添加一个类方法来概括这一点(假设您在 Model 之前定义了 ModelList):
class Model:
... your other methods ...
@classmethod
def List(self,elements=None):
return ModelList(self.__class__,elements)
# usage
class SomeModel(Model): pass
modelList = SomeModel.List([instance1,instance2,instance3])
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句