3

私が理解しているように、反復子を返すメソッドを使用forして、オブジェクトに対してループ構造を使用できます。__iter__次の__getattribute__メソッドを実装するオブジェクトがあります。

def __getattribute__(self,name):
    if name in ["read","readlines","readline","seek","__iter__","closed","fileno","flush","mode","tell","truncate","write","writelines","xreadlines"]:
        return getattr(self.file,name)
    return object.__getattribute__(self,name)

このクラスのオブジェクトがaあり、次のことが起こります。

>>> hasattr(a,"__iter__")
True
>>> for l in a: print l
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'TmpFile' object is not iterable
>>> for l in a.file: print l
...
>>>

そのため、 Python はaメソッドがあることを認識して__iter__いますが、反復可能であるとは考えていません。私は何を間違えましたか?これはpython 2.6.4です。

4

2 に答える 2

12

実際に__iter__はインスタンス メソッドではなく、クラス メソッドです。つまりobj.__class__.__iter__(obj)、 ではなく と呼ばれobj.__iter__()ます。

これは内部でのスロットの最適化によるもので、Python ランタイムが反復子をより速く設定できるようになっています。イテレータができるだけ高速であることが非常に重要であるため、これが必要です。

__getattribute__基になる型を定義することはできないclassため、このメソッドを動的に返すことはできません。これはほとんどの場合に当てはまり__metamethods__ます。実際のラッパーを作成する必要があります。

于 2011-03-14T16:08:33.227 に答える
4

一部の特別なメソッドは、クラスの作成時に最適化され、後で追加したり割り当てによってオーバーライドしたりすることはできません。次のようなドキュメントを参照してください__getattribute__

このメソッドは、言語構文または組み込み関数を介した暗黙的な呼び出しの結果として特別なメソッドを検索するときにバイパスされる場合があります。

この場合に必要なことは__iter__、呼び出しを転送する の直接実装を提供することです。

def __iter__(self):
    return self.file.__iter__()
于 2011-03-14T16:12:49.157 に答える