回答:
Pythonのイテレータオブジェクトはイテレータプロトコルに準拠しています。つまり、基本的には、との2つのメソッドを提供__iter__()  し   __next__()ます。  
__iter__イテレータオブジェクトを返し、暗黙的にループの開始時に呼び出されます。
この__next__()メソッドは次の値を返し、ループの増分ごとに暗黙的に呼び出されます。このメソッドは、返す値がなくなるとStopIteration例外を発生させます。これは、ループ構造によって暗黙的にキャプチャされ、反復を停止します。
カウンタの簡単な例を次に示します。
class Counter:
    def __init__(self, low, high):
        self.current = low - 1
        self.high = high
    def __iter__(self):
        return self
    def __next__(self): # Python 2: def next(self)
        self.current += 1
        if self.current < self.high:
            return self.current
        raise StopIteration
for c in Counter(3, 9):
    print(c)
これは印刷されます:
3
4
5
6
7
8
これは、前の回答で説明したように、ジェネレーターを使用して書く方が簡単です。
def counter(low, high):
    current = low
    while current < high:
        yield current
        current += 1
for c in counter(3, 9):
    print(c)
印刷出力は同じになります。内部的には、ジェネレーターオブジェクトはイテレータープロトコルをサポートし、クラスカウンターとほぼ同じような処理を行います。
David Mertzの記事「イテレーターとシンプルなジェネレーター」は、非常に優れた紹介です。
__next__。counterイテレータですが、シーケンスではありません。値は保存されません。たとえば、二重にネストされたforループでカウンターを使用しないでください。
                    __iter__(に加えて__init__)self.currentを割り当てます。それ以外の場合、オブジェクトは1回だけ反復できます。たとえば、と言った場合、一度ctr = Counters(3, 8)しか使用できませんfor c in ctr。
                    Counterはイテレータであり、イテレータは一度だけ反復されることになっています。でリセットself.currentする__iter__と、のネストされたループCounterが完全に壊れ、イテレータの想定されたすべての動作(呼び出しはべきiter等)に違反します。ctr複数回反復できるようにしたい場合は、反復可能でない反復可能である必要があり、__iter__呼び出されるたびに新しい反復を返します。混合して照合しようとすると(__iter__呼び出されたときに暗黙的にリセットされるイテレータ)、プロトコルに違反します。
                    Counterイテレータ以外の反復可能である場合は、__next__/ の定義をnext完全に削除し、おそらく__iter__この回答の最後に説明されているジェネレータと同じ形式のジェネレータ関数として再定義します(範囲の代わりに)引数からに来る__iter__彼らは、引数にはするだろう、__init__上に保存selfしてからアクセスselfで__iter__)。
                    反復関数を作成するには4つの方法があります。
__iter__and__next__(or nextPython 2.x))__getitem__)例:
# generator
def uc_gen(text):
    for char in text.upper():
        yield char
# generator expression
def uc_genexp(text):
    return (char for char in text.upper())
# iterator protocol
class uc_iter():
    def __init__(self, text):
        self.text = text.upper()
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
        try:
            result = self.text[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return result
# getitem method
class uc_getitem():
    def __init__(self, text):
        self.text = text.upper()
    def __getitem__(self, index):
        return self.text[index]
4つのメソッドすべての動作を確認するには:
for iterator in uc_gen, uc_genexp, uc_iter, uc_getitem:
    for ch in iterator('abcde'):
        print(ch, end=' ')
    print()
その結果:
A B C D E
A B C D E
A B C D E
A B C D E
注:
2つのジェネレーターのタイプ(uc_genおよびuc_genexp)はできませんreversed()。単純なイテレータ(uc_iter)には__reversed__魔法のメソッドが必要になります(docsによれば、新しいイテレータを返す必要がありますが、self(少なくともCPythonでは)機能します)。そしてgetitem iteratable(uc_getitem)は__len__魔法のメソッドを持っていなければなりません:
    # for uc_iter we add __reversed__ and update __next__
    def __reversed__(self):
        self.index = -1
        return self
    def __next__(self):
        try:
            result = self.text[self.index]
        except IndexError:
            raise StopIteration
        self.index += -1 if self.index < 0 else +1
        return result
    # for uc_getitem
    def __len__(self)
        return len(self.text)
無限に遅延評価された反復子に関するパニック大佐の二次的な質問に答えるために、上記の4つの方法のそれぞれを使用した例を次に示します。
# generator
def even_gen():
    result = 0
    while True:
        yield result
        result += 2
# generator expression
def even_genexp():
    return (num for num in even_gen())  # or even_iter or even_getitem
                                        # not much value under these circumstances
# iterator protocol
class even_iter():
    def __init__(self):
        self.value = 0
    def __iter__(self):
        return self
    def __next__(self):
        next_value = self.value
        self.value += 2
        return next_value
# getitem method
class even_getitem():
    def __getitem__(self, index):
        return index * 2
import random
for iterator in even_gen, even_genexp, even_iter, even_getitem:
    limit = random.randint(15, 30)
    count = 0
    for even in iterator():
        print even,
        count += 1
        if count >= limit:
            break
    print
その結果(少なくとも私のサンプル実行では):
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
どれを使用するかを選択するには?これは主に好みの問題です。私が最もよく目にする2つの方法は、ジェネレーターとイテレータープロトコル、およびハイブリッド(__iter__ジェネレーターを返す)です。
ジェネレータ式は、リスト内包表記を置き換えるのに役立ちます(それらは遅延するため、リソースを節約できます)。
以前のPython 2.xバージョンとの互換性が必要な場合は、を使用してください__getitem__。
uc_iter終了するとインスタンスの有効期限が切れます(それ以外の場合は無期限になります)。もう一度実行したい場合は、再度呼び出して新しいイテレータを取得する必要がありますuc_iter()。
                    self.index = 0で__iter__あなたは何度も繰り返すことができるように。そうでなければできません。
                    まず、itertoolsモジュールは、イテレーターが役立つあらゆる種類のケースで非常に便利ですが、Pythonでイテレーターを作成するために必要なものはすべて次のとおりです。
産出
かっこよくありませんか?Yieldは、関数の通常の戻り値を置き換えるために使用できます。オブジェクトはまったく同じように返されますが、状態を破棄して終了するのではなく、次の反復を実行するときのために状態を保存します。以下はitertools関数リストから直接引かれた動作の例です:
def count(n=0):
    while True:
        yield n
        n += 1
関数の説明(itertoolsモジュールのcount()関数です)で述べたように、nで始まる連続した整数を返すイテレータを生成します。
ジェネレーター式は、他の完全なワーム(素晴らしいワーム!)です。彼らはの代わりに使用することができるリスト読解リストの内包表記は、変数に割り当てられていない場合は、使用後に破壊されたメモリ内のリストを作成しますが、ジェネレータ式はジェネレータオブジェクトを作成することができます(メモリを節約するために...の空想の方法ですイテレータと言います)。ジェネレータ式の定義の例を次に示します。
gen = (n for n in xrange(0,11))これは、全範囲が0〜10の間で事前に決定されていることを除いて、上記のイテレータ定義と非常に似ています。
私はxrange()を見つけて(私はこれまでに見たことがないと思います...)、それを上記の例に追加しました。 xrange()はrange()の反復可能なバージョンであり、リストを事前に作成しないという利点があります。反復する巨大なデータのコーパスがあり、それを実行するのに大量のメモリしかない場合は、非常に便利です。
私はあなたのいくつかは、やって見るreturn selfの中で__iter__。私はちょうどことに注意することは望んでいた__iter__(これの必要性を取り除く自体が発電することができ__next__、および調達StopIteration例外)
class range:
  def __init__(self,a,b):
    self.a = a
    self.b = b
  def __iter__(self):
    i = self.a
    while i < self.b:
      yield i
      i+=1
もちろん、ここでは直接ジェネレータを作成することもできますが、より複雑なクラスの場合は便利です。
return selfで書くのはつまらない__iter__。私がyieldそれを使ってみるつもりだったとき、私はあなたのコードが私がやりたいことを正確に実行しているのを見つけました。
                    next()ますか?return iter(self).next()?
                    self.currentや他のカウンターを追跡する必要はありません。これがトップ投票の答えになるはずです!
                    iterしますが、それ自体はクラスのインスタンスではありません。
                    この質問は、反復子についてではなく、反復可能なオブジェクトについてです。Pythonでは、シーケンスも反復可能であるため、反復可能クラスを作成する1つの方法は、シーケンスのように動作させること、つまり、シーケンス__getitem__と__len__メソッドを提供することです。これをPython 2および3でテストしました。
class CustomRange:
    def __init__(self, low, high):
        self.low = low
        self.high = high
    def __getitem__(self, item):
        if item >= len(self):
            raise IndexError("CustomRange index out of range")
        return self.low + item
    def __len__(self):
        return self.high - self.low
cr = CustomRange(0, 10)
for i in cr:
    print(i)
__len__()メソッドは必要ありません。  __getitem__期待される動作を備えた単独で十分です。
                    このページのすべての回答は、複雑なオブジェクトに非常に適しています。しかし、属性として反復可能なタイプの組み込みを含有するもののために、のようなstr、list、setまたはdict、またはのいずれかの実装ではcollections.Iterable、あなたのクラスで、特定の物事を省略することができます。
class Test(object):
    def __init__(self, string):
        self.string = string
    def __iter__(self):
        # since your string is already iterable
        return (ch for ch in self.string)
        # or simply
        return self.string.__iter__()
        # also
        return iter(self.string)次のように使用できます。
for x in Test("abcde"):
    print(x)
# prints
# a
# b
# c
# d
# ereturn iter(self.string)。
                    これは、なしの反復可能な関数yieldです。iter関数と、listPython 2を囲むスコープ内の変更可能な状態()で状態を保持するクロージャーを利用します。  
def count(low, high):
    counter = [0]
    def tmp():
        val = low + counter[0]
        if val < high:
            counter[0] += 1
            return val
        return None
    return iter(tmp, None)Python 3の場合、クロージャーの状態はエンクロージングスコープの不変に保持nonlocalされ、ローカルスコープで状態変数を更新するために使用されます。  
def count(low, high):
    counter = 0
    def tmp():
        nonlocal counter
        val = low + counter
        if val < high:
            counter += 1
            return val
        return None
    return iter(tmp, None)  テスト;
for i in count(1,10):
    print(i)
1
2
3
4
5
6
7
8
9iterていますが、明確にするために:これは、yieldベースのジェネレーター関数を使用するよりも複雑で効率が悪いです。Pythonには、yieldここでは利用できないベースジェネレーター関数に対する多数のインタープリターサポートがあり、このコードを大幅に遅くしています。それでも賛成投票。
                    ここでマット・グレゴリーの答えに触発されて、a、b、...、z、aa、ab、...、zz、aaa、aab、...、zzy、zzzを返すもう少し複雑なイテレータがあります
    class AlphaCounter:
    def __init__(self, low, high):
        self.current = low
        self.high = high
    def __iter__(self):
        return self
    def __next__(self): # Python 3: def __next__(self)
        alpha = ' abcdefghijklmnopqrstuvwxyz'
        n_current = sum([(alpha.find(self.current[x])* 26**(len(self.current)-x-1)) for x in range(len(self.current))])
        n_high = sum([(alpha.find(self.high[x])* 26**(len(self.high)-x-1)) for x in range(len(self.high))])
        if n_current > n_high:
            raise StopIteration
        else:
            increment = True
            ret = ''
            for x in self.current[::-1]:
                if 'z' == x:
                    if increment:
                        ret += 'a'
                    else:
                        ret += 'z'
                else:
                    if increment:
                        ret += alpha[alpha.find(x)+1]
                        increment = False
                    else:
                        ret += x
            if increment:
                ret += 'a'
            tmp = self.current
            self.current = ret[::-1]
            return tmp
for c in AlphaCounter('a', 'zzz'):
    print(c)