私はすべてのユーザー定義の__slots__
属性のリストを返すはずの私の基底クラスに__dir__
カスタム実装を持っています。これは一般的に動作していますが、返す前に結果にsort
を実行しているように見えますが、私はそれを行うようにプログラムしていません(割り当てられた順序と同じ順序で属性が必要です)。カスタム__dir __()は、アルファベット順にソートされた属性のリストを返します
例:
class A:
__slots__ = ['b', 'a']
def __dir__(self):
slot_attrs = []
for parent_class in reversed(type(self).__mro__[:-1]):
for attr in parent_class.__slots__:
slot_attrs.append(attr)
for attr in self.__slots__:
slot_attrs.append(attr)
return slot_attrs
class B(A):
__slots__ = ['c', 'd']
pass
class C(B):
__slots__ = []
pass
class D:
__slots__ = ['b', 'a']
def slots(self):
slot_attrs = []
for parent_class in reversed(type(self).__mro__[:-1]):
for attr in parent_class.__slots__:
slot_attrs.append(attr)
for attr in self.__slots__:
slot_attrs.append(attr)
return slot_attrs
class E(D):
__slots__ = ['c', 'd']
pass
class F(E):
pass
はslots()
と__dir__()
の出力には、芋、同一であるべきです。
ではなく、この問題が発生した:dir()
を使用した場合
>>>c = C()
>>>f = F()
>>>print(dir(c))
['a', 'b', 'c', 'd']
>>>print(f.slots())
['b', 'a', 'c', 'd', 'c', 'd', 'c', 'd']
私はの種類は、それがアルファベット順に出力をソートすることを理解することができます - これはdocumented in the docsです。しかし、それはカスタムの__dir__
メソッドを定義していても出力をソートするというバグのように見えます。
2番目の出力は、ゲームを完全にオフにします。 dir
は、コードが同一であるがslots()
を呼び出すと重複した値を返すので、出力の重複を避けるために、何らかのフィルタを使用しています(おそらくset
)。
私はどちらもA)なぜそれが最初に起こるのか理解していないし、B)何が地球上でdir
がやっているのか理解していない。
ここにはどのようなポインタがありますか?
編集: - したがって、そのクラスが二度含まれている
後者の場合は__mro__
solved-では、呼び出し側のクラスだけでなく、それはから継承するすべてのクラスが含まれています。 すなわち:
>>>F.__mro__
(<class '__main__.F'>, <class '__main__.E'>, <class '__main__.D'>, <class 'object'>)
編集2:
プロットが厚くなります。
>>Couldn't __dir__ also be allowed to return a tuple?
no, because tuples are not sortable, and i don't want to
over complicate the c-side code of PyObject_Dir.
having __dir__ returning only a list is equivalent to
__repr__ returning only strings.
これは__dir__
が実装される前から、Cのソースコードから発信何かのように見える:コメントで参照さの問題は、この動作のソースにほんの少しより多くの光を当てます。
編集3:
私はissue on python's bug trackerを開きました。コンセンサスが何であるか見てみましょう。しかし、私はこれがbackburnerに置かれることを期待しています(もしあれば)dir()
は、主にIDLEなどの検査のために設計されたものです。
すべての非ユニークな要素は、削除されます。 'dir'はあなたのカスタムメソッドを呼び出していますが、それを後処理してドキュメンテーションをコンパイルします。 –
実際、idはそれらを削除しません - 私はちょうどそれをテストし、それもそれらを保持します。私は 'F'から' __slots__'を2回追加していました。 – nlsdfnbch
これは予期しない動作のようです。 'dir()'が '__dir __()'を呼び出すなら、私はそれが私の言うとおりにすると期待しています。 – nlsdfnbch