プログラム猿思慮深く、生涯学習の専門家は、スタートアップのチームで、現在どのチームリーダーである、技術スタックは、AndroidやPython、Java、および移動を必要とする、これが主な技術が私たちのチームをスタックです。
GitHubの:https://github.com/hylinux1024
マイクロチャネルパブリック番号:生涯現像剤(angrycode)
でPython
(反復可能Iterable
(イテレータ)Iterator
)及び発電機(Generator
)これらの概念がしばしば使用され、これらのいくつかの初心者はしばしば概念と混同され、把握するいくつかの概念を置くための時間です。
0x00の反復可能な(反復処理可能)
単に長い実現の実現に限り、(Pythonではすべてがオブジェクトである)オブジェクトを置く__iter__()
方法、そしてisinstance()
チェックが機能であるIterable
オブジェクトは、
例えば
class IterObj:
def __iter__(self):
# 这里简单地返回自身
# 但实际情况可能不会这么写
# 而是通过内置的可迭代对象来实现
# 下文的列子中将会展示
return self
上記クラスの定義IterObj
および実装する__iter__()
方法を、これは缶の反復(反復処理可能)オブジェクト
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) # false
このクラスを覚えておいてください、私たちは、このクラス定義の下に表示されます。
共通の反復可能オブジェクト
ではPython
その共通のiterableはそれを持っていますか?
- セットまたはシーケンスタイプ(例えば
list
、tuple
、set
、dict
、str
) - Fileオブジェクト
- クラスで定義され
__iter__()
た方法のオブジェクトと考えることができるIterable
オブジェクトが、反復カスタムオブジェクトができるようにfor
正しいサイクルを使用し、確保する必要がある__iter__()
実装では(すなわち、内蔵によって正確でなければならないiter()
の機能オンIterator
オブジェクト。についてIterator
以下説明はちょうどことを覚えて、ピットを残すためにここになりますiter()
関数は、その後に、反復可能なイテレータオブジェクトに変身する能力であるfor
)を使用
- 唯一のクラスで実装されていれば達成
__getitem__()
オブジェクトが可能なiter()
反復の対象イテレータ関数にではなく、自分自身で変換します。だから、オブジェクトができた場合for
のサイクルで実行されますが、必ずしもではないIterable
オブジェクト。
約1,2点は、私たちは次のことを確認することができます
print(isinstance([], Iterable)) # true list 是可迭代的
print(isinstance({}, Iterable)) # true 字典是可迭代的
print(isinstance((), Iterable)) # true 元组是可迭代的
print(isinstance(set(), Iterable)) # true set是可迭代的
print(isinstance('', Iterable)) # true 字符串是可迭代的
currPath = os.path.dirname(os.path.abspath(__file__))
with open(currPath+'/model.py') as file:
print(isinstance(file, Iterable)) # true
私たちは、見てポイント3、
print(hasattr([], "__iter__")) # true
print(hasattr({}, "__iter__")) # true
print(hasattr((), "__iter__")) # true
print(hasattr('', "__iter__")) # true
これらの組み込みセットまたはシーケンスオブジェクトが持っている__iter__
、彼らはメソッドと同じ名前を達成しているプロパティを。しかし、この反復可能オブジェクトをしたいfor
、それはビルトインでなければならず、使用サイクルにあるiter()
関数呼び出しとに変換Iterator
するオブジェクト。
例えば、我々は組み込みのイテレート可能オブジェクトを見て
print(iter([])) # <list_iterator object at 0x110243f28>
print(iter({})) # <dict_keyiterator object at 0x110234408>
print(iter(())) # <tuple_iterator object at 0x110243f28>
print(iter('')) # <str_iterator object at 0x110243f28>
これらは、それぞれ対応するイテレータ(に変換されIterator
)オブジェクト。
今すぐ戻っての定義の先頭を見てIterObj
クラス
class IterObj:
def __iter__(self):
return self
it = IterObj()
print(iter(it))
我々が使用するiter()
機能を、今回Jiangzaiコンソールには、以下の情報をプリントアウトします:
Traceback (most recent call last):
File "/Users/mac/PycharmProjects/iterable_iterator_generator.py", line 71, in <module>
print(iter(it))
TypeError: iter() returned non-iterator of type 'IterObj'
エラーの種類があることを意味し、発生したiter()
関数がイテレータ型に「非反復子」を転送することはできません。
次に、どのように一つは、反復することができます(Iterable
イテレータ(に)オブジェクトIterator
)オブジェクト?
私たちは、改訂よIterObj
クラスの定義を
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
def __iter__(self):
return iter(self.a)
私たちは、で指定されたコンストラクタを定義a
リストは、また、実装__iter__()
方法を。
修飾されたクラスは、することができるiter()
すなわちであってもよく、機能を呼び出しfor
使用サイクル
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) # false
print(iter(it)) # <list_iterator object at 0x102007278>
for i in it:
print(i) # 将打印3、5、7、11、13、17、19元素
したがってイテレータオブジェクトを定義するとき、我々はに細心の注意を払う__iter__()
オブジェクト(例えば、上記セットは、配列、または他のファイルを正しく定義することができる反復の数で知られており、一般的には、実装内部処理ロジック反復可能)を達成するために私たちを支援するために
点4記載ことを意味iter()
機能を実現することができる__getitem__()
方法イテレータオブジェクトに変換し、ターゲットがであってもよくfor
、使用サイクルが、場合isinstance()
検出方法時間は、それはイテレータオブジェクトではありません。
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
def __getitem__(self, i):
return self.a[i]
it = IterObj()
print(isinstance(it, Iterable)) # false
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) false
print(hasattr(it, "__iter__")) # false
print(iter(it)) # <iterator object at 0x10b231278>
for i in it:
print(i) # 将打印出3、5、7、11、13、17、19
この例では、CAN示す図でfor
使用されているオブジェクトが、それは必ずしもイテレート可能オブジェクトではありません。
今、私たちは要約を行います。
- 繰り返しオブジェクト達成することにある
__iter__()
オブジェクトのメソッドを - それはにあることがあり
for
、それは満たしている必要があり、使用サイクルiter()
コール(すなわち、間違っていることはありません。この関数を呼び出し、適切に回すことができるIterator
オブジェクト) - 反復可能で知られている私たちのカスタム反復可能オブジェクトを達成するために支援することができます。
- オブジェクトが実装する
__getitem__()
方法をすることができるiter()
関数に変換Iterator
することができるfor
ループで使用されるが、それはイテレータオブジェクトでない(使用可能でisinstance検出方法())
0x01の反復子(イテレータ)
多くの場所は、上記しているIterator
今、私たちはピットを埋めるために持っています、。
私たちは、イテレータのための反復の概念を理解することができた場合には、よりよく理解されます。
オブジェクトが実装__iter__()
及び__next__()
方法、それはイテレータオブジェクトです。例えば
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
self.n = len(self.a)
self.i = 0
def __iter__(self):
return iter(self.a)
def __next__(self):
while self.i < self.n:
v = self.a[self.i]
self.i += 1
return v
else:
self.i = 0
raise StopIteration()
ではIterObj
、リスト、コンストラクタの定義a
、リストの長さはn
、インデックスi
。
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # true
print(isinstance(it, Generator)) # false
print(hasattr(it, "__iter__")) # true
print(hasattr(it, "__next__")) # true
当社は、上記見つけることができ
、コレクションやオブジェクトが反復シーケンスではなく、イテレータです
print(isinstance([], Iterator)) # false
print(isinstance({}, Iterator)) # false
print(isinstance((), Iterator)) # false
print(isinstance(set(), Iterator)) # false
print(isinstance('', Iterator)) # false
ファイルオブジェクトは、イテレータです
currPath = os.path.dirname(os.path.abspath(__file__))
with open(currPath+'/model.py') as file:
print(isinstance(file, Iterator)) # true
反復子(Iterator
)オブジェクトのみができないfor
サイクルを使用して、組み込み機能もできnext()
関数と呼ばれます。例えば
it = IterObj()
next(it) # 3
next(it) # 5
0x02のジェネレータ(発電機)
今度は、ビルダーが何であるかを見てみましょうか?
発電機はまた、両方の反復イテレータです
発電機は、2つの方法が定義されています。
- リストビルダ
- 使用して
yield
ファンクションジェネレータの定義を
ケース1を見てください
g = (x * 2 for x in range(10)) # 0~18的偶数生成器
print(isinstance(g, Iterable)) # true
print(isinstance(g, Iterator)) # true
print(isinstance(g, Generator)) # true
print(hasattr(g, "__iter__")) # true
print(hasattr(g, "__next__")) # true
print(next(g)) # 0
print(next(g)) # 2
データを必要なときにのみ計算されますリストビルダは、膨大なリストを生成するために多くのメモリを消費する必要はないかもしれません。
ケース2を見て
def gen():
for i in range(10):
yield i
このyield
効果は、に相当しreturn
、この関数の次数を返すある[0,10)
自然数で製造することができるnext()
、またはfor
反復するループ。
プログラムは、遭遇するとyield
、キーワード、ジェネレータ関数の戻りを、再び実行するまでnext()
の機能を、それは、つまり、最後の実行ポイント関数が返すから継続されますyield
終了時に、関数の実行、変数などの位置情報を保存し、この上で、再実行時にyield
終了場所をダウンし続けます。
でPython
発電機のこれらの機能を利用コルーチンを実装することができます。コルーチンは、軽量スレッドとして理解することができ、高い並行性シナリオの治療に関して、それをスレッド多くの利点を有します。
ここで実現コルーチンの表情で生産-消費者モデル
def producer(c):
n = 0
while n < 5:
n += 1
print('producer {}'.format(n))
r = c.send(n)
print('consumer return {}'.format(r))
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('consumer {} '.format(n))
r = 'ok'
if __name__ == '__main__':
c = consumer()
next(c) # 启动consumer
producer(c)
このコードは次のような効果を行い、
producer 1
consumer 1
producer return ok
producer 2
consumer 2
producer return ok
producer 3
consumer 3
producer return ok
コルーチンは達成CPU
同時実行を達成するために2つの機能の切り替え効果を。