19

サブクラス化するクラスと、関数ListViewを実装した 2 つのカスタム ミックスインを作成しました。get_context_data子クラスでこの関数をオーバーライドしたかった:

from django.views.generic import ListView

class ListSortedMixin(object):
    def get_context_data(self, **kwargs):
        print 'ListSortedMixin'
        return kwargs

class ListPaginatedMixin(object):
    def get_context_data(self, **kwargs):
        print 'ListPaginatedMixin'
        return kwargs

class MyListView(ListSortedMixin, ListPaginatedMixin, ListView):
  def get_context_data(self, **context):
    super(ListSortedMixin,self).get_context_data(**context)
    super(ListPaginatedMixin,self).get_context_data(**context)
    return context

実行するMyListViewと、印刷されるだけ"ListSortedMixin"です。何らかの理由で python がListSortedMixin.get_context_data代わりに実行されていMyListView.get_context_dataます。なんで?

継承順序を に変更するとListPaginatedMixin, ListSortedMixin, ListViewListPaginatedMixin.get_context_dataが実行されます。

get_context_data関数をオーバーライドするにはどうすればよいですか?

4

3 に答える 3

10

あなたがしようとしているのは、上書きされたメソッドを固定された順序で呼び出すことです。次の構文を使用します。

class MyListView(ListSortedMixin, ListPaginatedMixin, ListView):
  def get_context_data(self, **context):
    ListSortedMixin.get_context_data(self, **context)
    ListPaginatedMixin.get_context_data(self, **context)
    return context

この場合、スーパーは機能しません。のマニュアルを参照してくださいsuper(type[, object])

メソッド呼び出しをtypeの親または兄弟クラスに委譲するプロキシ オブジェクトを返します。これは、クラスでオーバーライドされた継承メソッドにアクセスする場合に便利です。検索順序は、タイプ自体がスキップされることを除いて、getattr() で使用される順序と同じです。

super には 2 つの典型的な使用例があります。単一継承のクラス階層では、親クラスに明示的に名前を付けなくても super を使用して親クラスを参照できるため、コードがより保守しやすくなります。この使用法は、他のプログラミング言語での super の使用法とよく似ています。

2 番目の使用例は、動的な実行環境で協調多重継承をサポートすることです。この使用例は Python に固有のものであり、静的にコンパイルされた言語や単一継承のみをサポートする言語には見られません。これにより、複数の基本クラスが同じメソッドを実装する「ダイヤモンド ダイアグラム」を実装できます。優れた設計では、このメソッドがすべての場合に同じ呼び出しシグネチャを持つように指示されます (呼び出しの順序は実行時に決定され、その順序はクラス階層の変更に適応し、その順序には実行前に不明な兄弟クラスが含まれる可能性があるため) )。

したがって、スーパーの引数は、取得する親または兄弟クラスのプロキシを持つクラスです。super(ListSortedMixin,self).get_context_data(**context)必ずしも を呼び出すとは限りませget_context_dataListSortedMixin。メソッド解決順序 (MRO) に依存します。これは、次を使用して取得できます。print MyListView.__mro__

親や兄弟のsuper()呼び方もそうです。get_context_data実行の順序は、クラス階層の変更に適応します。これは、その順序に、実行前に不明な兄弟クラスが含まれる可能性があるためです。

于 2012-03-30T08:57:25.670 に答える
0

Python を初めて使用し、ここで回答を探しているほとんどの人は、Python 2 ではなく Python 3 を使用することになるので、ここで小さな更新を行います。

class Parent(object):
    def get_context_data(self, **kwargs):
        print('Parent')

class ListSortedMixin(object):
    def get_context_data(self, **kwargs):
        print('ListSortedMixin')
        return super().get_context_data(**kwargs)

class ListPaginatedMixin(object):
    def get_context_data(self, **kwargs):
        print('ListPaginatedMixin')
        return super().get_context_data(**kwargs)

class MyListView(ListSortedMixin, ListPaginatedMixin, Parent):
    def get_context_data(self, **kwargs):
        return super().get_context_data(**kwargs)


m = MyListView()
m.get_context_data(l='l')
于 2019-12-06T18:02:11.663 に答える