多个inheritan中的Python意外MRO

2024-10-04 11:34:29 发布

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

我的视图集和mixin有下面的类设计。我的问题是,当我从SomeModelViewSet调用super().create()时,它调用的是视图集的update(),而不是MixinAupdate()。呼叫MixinA.create(self)是一种方式吗?你知道吗

请提醒我,如果这是坏的设计。你知道吗

免责声明:我从create()调用update()是因为解决了一些不常见的规范

混合物.py

class MixinA(mixins.CreateModelMixin, mixins.UpdateModelMixin):
    def create(self, request, *args, left=None, right=None **kwargs):
        # ...
        self.update(request, left=left, right=right)

    def update(self, request, *args, left=None, right=None, **kwargs):
        # ...

class MixinB(mixins.DestroyModelMixin):
    def destroy(self, request, *args, **kwargs):
        # ...

class MixinC(mixins.ListModelMixin):
    def list(self, request, *args, **kwargs)
        # ...

视图集.py

class BaseViewSet(MixinC):
    # ...

class MyViewSet(MixinA, MixinB, BaseViewSet):
    pass

视图.py

class SomeModelViewSet(MyViewSet):
    def create(self, request, pk=None, **kwargs):
        a = someObj(pk=pk)
        b = someObj(pk=None)
        return super().create(request, left = a, left = b, **kwargs)

    def update(self, request, first_pk=None, second_pk=None, **kwargs):
        a = someObj(pk=first_pk)
        b = someObj(pk=second_pk)
        return super().update(request, left=a, right=b)

    def destroy(self, request, first_pk=None, second_pk=None, **kwargs):
        lookup = {'first__pk': first_pk, 'second_pk': second_pk}
        return super().destroy(request, **lookup)

EDIT

MRO看起来是这样的

SomeModelViewSet.create() -> MixinA.create() -> SomeModelViewSet.update() -> MixinA.update()

我想要的是下面这个,因此self.update()中的MixinA.create()

SomeModelViewSet.create() -> MixinA.create() -> MixinA.update()

参数leftrightMixinA.create()SomeModelViewSet.update()之间变化

create(): TripDispatcherViewSet
    # left: Klass(pk='1')
    # right: Klass(pk=None)
create(): IntermediaryModelCreateModelMixin
    # left: Klass(pk='1')
    # right: Klass(pk=None)
update(): TripDispatcherViewSet
    # left: Klass(pk=None)
    # right: Klass(pk=None)
update(): IntermediaryModelCreateModelMixin
    #left: Klass(pk=None)
    # right: Klass(pk=None)

Tags: selfrightnonerequestdefcreateupdateleft
1条回答
网友
1楼 · 发布于 2024-10-04 11:34:29

调用的顺序是有意义的。调用self.update()时,要求解释器在self对象上找到适当的update()方法,这是根据MRO完成的,因此会找到SomeModelViewSet.update()。从MixinA类的方法内部调用它的事实与此无关。你知道吗

是的,你可以打电话给MixinA.update(self)来解决这个问题。然而,这里的基本问题是,您调用的是为继承而设计的API,而实际上并不需要继承的行为。因此,在我看来,更好的设计是通过使用不同的方法来明确地承认这一点。比如:

class MixinA(mixins.CreateModelMixin, mixins.UpdateModelMixin):
    def create(self, ...):
        ...
        self._my_update(...)

    def update(self, ...):
        self._my_update(...)

    def _my_update(self, ...):
        ...

这里的优点是,您将update()的API分离出来,该API是为继承而设计的,它与您想要利用的MixinA.create()的实现细节分离开来。你知道吗

相关问题 更多 >