3

直接type.mro()反復するのではなく、呼び出す必要がある理由はありますか? type.__mro__文字通り、アクセスが 13 倍高速です (36ns 対 488 ns)。

キャッシュを探しているときに偶然見つけましたtype.mro()。それは正当に思えますが、疑問に思います: に頼ることができますかtype.__mro__、それとも電話する必要がありますtype.mro()か? そして、どのような条件下で前者を回避できますか?

type.__mro__さらに重要なことは、無効になるにはどのような条件が発生する必要があるかということです。

たとえば、既存のクラスの mro を変更する新しいサブクラスが定義/作成された場合、既存のクラスは.__mro__すぐに更新されますか? これは、新しいクラスを作成するたびに発生しますか? クラスタイプの一部になりますか?どの部分?..またはそれは何type.mro()ですか?

もちろん、type.__mro__実際には、特定のタイプの mro 内のオブジェクトを指すキャッシュされた名前のタプルであると仮定しています。その仮定が間違っている場合。では、それは何ですか?(おそらく記述子か何か..)そして、なぜそれを使用できる/できないのですか?

編集:それが記述子である場合、次の両方として、その魔法を学びたいと思います:type(type.__mro__) is tupleおよびtype(type(type).__mro__) is tuple(つまり:おそらく記述子ではない)

編集:これがどの程度関連しているかはわかりませんがtype('whatever').mro()、リストをtype('whatever').__mro__返しますが、タプルを返します。(いや?)幸いなことに、そのリストに追加しても、問題の型 (この場合は str) の of/on__mro__への呼び出しまたはその後の呼び出しは変更されません。.mro()

助けてくれてありがとう!

4

1 に答える 1

4

ドキュメントによると:

class.__mro__

この属性は、メソッドの解決中に基本クラスを探すときに考慮されるクラスのタプルです。

class.mro()

このメソッドをメタクラスでオーバーライドして、そのインスタンスのメソッド解決順序をカスタマイズできます。クラスのインスタンス化時に呼び出され、その結果が に格納され__mro__ます。

そう__mro__です、キャッシュであるというあなたの仮定は正しいです。メタクラスがmro()常に同じものを返す場合、またはメタクラスがない場合は、安全に使用できます__mro__

于 2015-09-03T04:33:26.770 に答える