2016-11-06 2 views
7

obj == iter(obj)は、objが繰り返し反復不可能であることを意味し、逆も同様です。私は、ドキュメント内の任意のそのような文言を見ていないが、this commentによると、オブジェクトを繰り返し反復可能by testing if iter(obj) is obj標準ライブラリをチェックしている場合:オブジェクトが繰返し反復可能であることの検出

@agf:依存しているPythonの標準ライブラリの一部であり、この仕様の部分でthey detect whether something is an iterator/generator by testing if iter(obj) is obj:です。真のイテレータ/ジェネレータオブジェクトは、同一性関数として__iter__が定義されているためです。テストが真の場合は、反復を繰り返すためにlistに変換されます。そうでない場合、オブジェクトは反復可能に反復可能であり、そのまま使用できます。
- ShadowRangerJun 3 at 17:23

ドキュメントはobjがイテレータであれば、それはそのiter(obj)戻りobjが必要だという状態を行います。しかし、反復不可能なオブジェクトがiter(obj) is objを使って特定できると結論付けるには十分だとは思いません。

答えて

5

すべてのイテレータはイテラブルですが、すべてのイテレータはイテレータではありません。

container.__iter__()

一つの方法は、反復処理サポートを提供するために、コンテナオブジェクトのために定義される必要がある:

反復可能の唯一requirementは、イテレータを返す__iter__()メソッドを定義することです イテレータオブジェクトを返します。

iterator.__iter__()
戻りイテレータオブジェクト:これは__iter__()方法that returns the object itselfを有する

iteratorは、二つの要件がありイテレータプロトコルを、従わなければなりません自体。

  • それは呼び出しごとに次の項目を返す__next__()方法を持っている、そして、一度使い果たし、StopIterationon every subsequent callを提起:

    反復子の__next__()方法はStopIterationを上げたら、それはそうし続ける必要がありますその後の呼び出しでこのプロパティに従わない実装は壊れているとみなされます。

  • これらの要件は、イテレータが反復されることはありませんことを、あなたは常に反復可能なイテレータ(および定義によるので、またとない)であることを確認できることを意味iter(obj) is objTrueであることを確認することにより:

    def is_unrepeatable(obj): 
        return iter(obj) is obj 
    

    ただし、の場合、繰り返し可能性の唯一の要件は、iter(obj)の一部を返すためです。イテレータは、できません。であることを証明しています。 iterableは__iter__()メソッドを定義して、呼び出されるたびに異なる動作を持つイテレータを返すことができます。たとえば、最初に呼び出されたときにその要素を反復するイテレータを返すことができますが、その後の呼び出しでは直ちにStopIteration

    この動作は奇妙な(迷惑な)ものですが、禁止されていません。ここでは、イテレータではない非反復反復可能なクラスの例です:

    class Unrepeatable: 
    
        def __init__(self, iterable): 
         self.iterable = iterable 
         self.exhausted = False 
    
        def __iter__(self): 
         if self.exhausted: 
          return 
         else: 
          self.exhausted = True 
          yield from self.iterable 
    

    >>> x = Unrepeatable([1,2,3]) 
    >>> list(x) 
    [1, 2, 3] 
    >>> list(x) 
    [] 
    >>> iter(x) is x 
    False 
    >>> 
    

    私はひどく行儀な「偽の反復子」と呼ぶことを躊躇しないだろう、と私ができますあなたが野生のものを見つけることができる状況を考えていますが、上記のように、それは可能です。

    +2

    さらに進んでください:病理学的な例を思い浮かべるのは自明ですが、実際には「iter(obj)is obj'<=> obj is reiterable」と仮定するのは安全です。この非常に問題の核心のpython開発者によるこの[discussion](https://mail.python.org/pipermail/python-ideas/2013-September/023241.html)を見てください。私は無駄でも無意味でもない反復不可能で反復不可能な反復可能な例を見ていません。 –

    +2

    @shadydog:少なくともPython 2.7では、 'urllib.urlopen'は実際の反例です。これは 'iter(obj)is obj'を持つオブジェクトを返しますが、ファイルのようなワンショット反復動作を伴います。私はPython 3の同等物が同じように動作するかどうかはわかりません。 'iter(x)is iter(x)'は 'urllib.urlopen'をキャッチするやや信頼性の高いチェックです。誰もが実際に使っていることで失敗するものは分かりませんが、それでもすべてを捕まえることはできません。 – user2357112

    関連する問題