タプルを反転し、リストを反転すると、異なる型のオブジェクトが返されます。
>>> reversed((1,2))
<reversed at 0x7fffe802f748>
>>> reversed([1,2])
<list_reverseiterator at 0x7fffebdd4400>
彼らは同じdir
です。どちらの型も他方のサブクラスではありません。
何故ですか?一方ができて他方ができないことは何ですか?
タプルを反転し、リストを反転すると、異なる型のオブジェクトが返されます。
>>> reversed((1,2))
<reversed at 0x7fffe802f748>
>>> reversed([1,2])
<list_reverseiterator at 0x7fffebdd4400>
彼らは同じdir
です。どちらの型も他方のサブクラスではありません。
何故ですか?一方ができて他方ができないことは何ですか?
基本的に、リストは__reversed__
メソッドを実装し、特殊なオブジェクトを返しますが、任意のシーケンスtuple
のデフォルトの実装にフォールバックします:reversed
>>> list.__reversed__
<method '__reversed__' of 'list' objects>
>>> tuple.__reversed__
AttributeError: type object 'tuple' has no attribute '__reversed__'
さて、リストがデフォルトでシーケンス オブジェクトにならない理由はreversed
、リスト オブジェクト自体のソース コードで見つける必要があります。おそらく、いくつかの内部list
属性に直接アクセスすることで、いくつかの最適化が可能になります。
実際に C コードを見ると、違いはほとんどなく、特に目立ったものはありません。
特別なリストの実装は、 実際に他の Python シーケンスを a にコピーする__reversed__
Python2 の時代の残り物 だと思います。タプルには十分でした)。reversed
list
enumreverse
__reversed__
のスロットをコメントアウトするだけ でlistobject.c
、Python とそのリストが何も起こらなかったかのように機能し、デフォルトで一般的なケースになると確信していますreversed
。
Pythonのドキュメントによると:
object.__reversed__(self)
reversed()
逆反復を実装するために組み込みによって呼び出されます (存在する場合) 。コンテナー内のすべてのオブジェクトを逆の順序で繰り返す新しい iterator オブジェクトを返す必要があります。
__reversed__()
メソッドが提供されていない場合、reversed()
ビルトインはシーケンス プロトコル (__len__()
および__getitem__()
) を使用するようにフォールバックします。シーケンス プロトコルをサポートするオブジェクトは、__reversed__()
によって提供される実装よりも効率的な実装を提供できる場合に のみ提供する必要がありreversed()
ます。