__mro__

そうそう、「すべての親クラスを探索し終わってから祖父クラスを探す」という理解をしている人が多い(僕も含めて)ようだけど、それは間違い。

ほほう。単純に旧スタイルクラスは深さ優先検索、新スタイルクラスは幅優先検索ではないのか…。間違えて理解していたなあ。て言うか、『Pythonクイックリファレンス』ではダイヤモンド継承の例しか載ってなかったと思うので勘違いしやすいかも。


Java Puzzlers』から引用したクイズは反響が大きかった気がするのでPythonクイズをたまには書こうかな。最近気になっていたのは『Pythonチュートリアル』の用語集の中で、オブジェクトに__hash__が定義されていればそのオブジェクトを辞書のキーにすることが可能という内容の記述があったけど多分厳密には間違いではないかな。

>>> class Foo:pass
...
>>> f = Foo()
>>> f.__hash__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Foo instance has no attribute '__hash__'
>>> d = {}
>>> d[f] = 1
>>> d[f]
1 

これはどう解釈すべきなのかな?私の解釈の間違いかな?私の認識では、__hash__が定義されていれば辞書のキーとして可能ではなく、辞書のキーにするには__hash__をオーバーライドすべきということなのだが。


私自身、__hash__が定義されていない場合にキーとした場合、どういうルールでハッシュ値を決めているのか分からない。ハッシュ値自身は恐らくid(obj)だと思う。それとも、上の例のfは__hash__を持っているが、見えないだけ?でもそんなルールどこにも書いてないよなあ。ここら辺のルールはどこかに書いてあるのかな…?