web-dev-qa-db-fra.com

Comment l'ordre des mixins affecte-t-il la classe dérivée?

Dites, j'ai les mixins suivants qui se chevauchent en touchant dispatch():

class FooMixin(object):
    def dispatch(self, *args, **kwargs):
        # perform check A
        ...
        return super(FooMixin, self).dispatch(*args, **kwargs)

class BarMixin(object):
    def dispatch(self, *args, **kwargs):
        # perform check B
        ...
        return super(FooMixin, self).dispatch(*args, **kwargs)

Si je veux que ma vue passe par la commande, cochez A -> cochez B, mon code doit-il être MyView(FooMixin, BarMixin, View) ou MyView(BarMixin, FooMixin, View)?

Et pourquoi mettons-nous toujours View ou ses sous-classes après les mixins? (J'ai remarqué cela en lisant le code source des vues génériques Django, mais je ne connais pas la justification, le cas échéant)

49
tamakisquare

Le MRO est fondamentalement la profondeur d'abord, de gauche à droite. Voir Ordre de résolution des méthodes (MRO) dans un nouveau style Python classes pour plus d'informations.

Vous pouvez regarder le __mro__ attribute de la classe à vérifier, mais FooMixin devrait être le premier si vous voulez faire "check A" en premier.

class UltimateBase(object):
    def dispatch(self, *args, **kwargs):
        print 'base dispatch'

class FooMixin(object):
    def dispatch(self, *args, **kwargs):
        print 'perform check A'
        return super(FooMixin, self).dispatch(*args, **kwargs)

class BarMixin(object):
    def dispatch(self, *args, **kwargs):
        print 'perform check B'
        return super(BarMixin, self).dispatch(*args, **kwargs)

class FooBar(FooMixin, BarMixin, UltimateBase):
    pass

FooBar().dispatch()

Impressions:

perform check A
perform check B
base dispatch

View doit être le dernier pour qu'il "attrape" toutes les recherches d'attributs qui n'étaient sur aucun mixins, sans cacher aucune méthode sur ces mixins. Je ne suis pas sûr de comprendre cette partie de votre question - en quoi consiste-t-il "pourquoi est-il ajouté" ou "pourquoi est-il ajouté en dernier"?

73
agf