講師：こんにちは､ お帰りなさい｡
このビデオでは､ ジェネレータクラスとイテレータについて説明します｡
ここでは､ 前回のビデオで行った100個の数字ジェネレータを実装したクラスをお見せします｡
ということで､ FirstHundredGeneratorと呼ぶことにします｡
こんな感じで､ initメソッドを定義していきます｡
これは数字を0としてスタートさせるもので､
次にアンダースコア､ アンダースコア､ ネクストメソッドを定義します｡
クラスでnextメソッドを定義すると､ 任意のオブジェクトは､
次のように､ 私のオブジェクトのnextを呼び出すことができます｡
つまり､ これまたダンダンメソッドで次を呼べるようにしたわけです｡
また､ これはPythonにかなり重要なことを教えてくれています｡
その様子は､ これから見ていきます｡
つまり､ 100個の数字を生成したかったら､ 自己を取得すればいいだけなのです｡
を返し､
それを1つインクリメントする｡
だから､ もし､ セルフ｡ が100より小さい場合､
ここではyieldキーワードを使いません｡
クラスジェネレータでは必要ないからです｡
すみません､ こういうので｡ (笑) 間違った解釈をされる可能性のあることは言わないようにするだけです｡
混乱させないためにね｡
どうするかというと､ 数値が100より小さければ､
それを変数に入れ､ 数値を1ずつ増やしていき､
現在の数値､ つまり前の値を返すので､
0になるわけです｡
自己を増大させる｡ を1つずつ加算していくと､ 0を返します｡
なるほど｡
さて､ クラスで重要なことは､
もし数字を返すのをやめたいなら､ 例えば､
ここでは100に達したときに止めるためのループを使っていないことです｡
そこで､ 100に達した時点で､ Stop Iterationと呼ばれる特別なエラーを発生させなければならない｡
Stop Iterationエラーは､ Pythonにこのジェネレータの終わりに到達したことを知らせます｡
ジェネレーターと言いつつ､ 若干ひるんでいるのは､ あのーこちらです｡
というのも､ これは基本的にジェネレーターで､ ゼロからスタートして､
新しい数字を返すかどうかを決め､ その数字を取得し､ それを返すとプログラムが止まるというものだからです｡
しかし､ あなたのオブジェクトは残っており､ 自己を記憶しています｡ の番号を入力します｡
つまり､ 私のジェネレーターがあれば､ それが最初の100台のジェネレーターです｡
マイゲン｡ の数値は､ もちろんスタート時点ではゼロです｡
そうだろ？
それを見せてあげましょう｡
マイゲン......冒頭の数字「0」｡
マイゲンをすれば｡ のように次へ､ そして私のゲンをプリントする｡
の番号をもう一度､
手に入れることができます｡
それはそれで意味があるのでは？
なぜなら､ ここでの次のメソッドは､ 数値が100より小さいかどうかをチェックし､
1つずつインクリメントしているからです｡
だから､ これらはすべて理にかなっているのです｡
さて､ ジェネレータのように動作させるためには､
次のようにnext of my genと言えばいいわけです｡
そして､ これをもう一度実行すると､ 同じものが出てきます｡
もちろん､ next of my genは､
実際にはインクリメントする前の数値を返しています｡
だから､ 私のゲン担ぎを印刷するのではなく という数字が表示され､
ここで私の遺伝子の次を表示することもできます｡
最初にnextを呼ぶと､ 現在値は0ですが､ selfをインクリメントしています｡
を1つずつ増やしていく｡
次にnextを呼ぶと､
またその数値が1ずつ増えていくが､
前の値である1が返ってくる｡
つまり､ これはまさに発電機のような動作をしているわけです｡
100までの値を全てリストに格納しているわけではありません｡
ひとつひとつ丁寧にお渡ししています｡
次の関数を呼び出すときに生成しているのです｡
すみません､ 次の方法です｡
ちなみに､ Python 3ではdunder nextが新登場｡
そのため､ Python 2を使用している場合は､
アンダースコアなしでnextを定義する必要があります｡
それはPython 2だけの話です｡
Python 3を使用している場合は､ 次にdunderを使用します｡
さて､ このダンダンnextメソッドを持つオブジェクトは､
すべてイテレータと呼ばれます｡
このように､ すべてのジェネレータはイテレータであるが､
その逆はない｡
だから､ 数字を生成しないイテレータを持つことができる｡
例えば､ 最初の数字ジェネレータを､ ジェネレータではなく､ 最初の100個のイテレータのように､
リストの一部を返すように変更する場合､ ここにinitメソッドを持つことができます､
それはselfと言います｡
の数字は､
1､ 2､ 3､ 4､ 5です｡
明らかに､ 最初の100個ではなく､
最初の5個のイテレータです｡
つまり､ このインデックスを返すようになるわけです｡
ゼロ､ そして返す数字は1～5までです｡
そしてまた､ 次の方法は､ Iがselfのlenより小さかったら､
というだけのものです｡ の数値は､ self.
数字 I.
そうだろ？
Else raise 反復を停止する｡
すみません､ そんなによく見えないと思いますが､ これでよしとします｡
つまり､ 私たちがやっていることは､ 何も生み出していないのです｡
Iが1より小さかったら､
Iプラス1を返せということなんです､
もちろんそうしなければなりません｡
1をインクリメントしなければならないし､ Iももちろん1ずつインクリメントしなければならない｡
繰り返しになりますが､ 私たちは新しい数字を生み出しているわけではありません｡
現在のインデックスを記録しているのですが､ そのためには､
何らかの方法で､ これが自己であるべきなのです｡
ちなみに私は｡
この例を実際に用意したわけではないことはおわかりいただけると思いますが､ すべてのジェネレータ､
すべてのイテレータがジェネレータでなければならないわけではないことを手早く示したかっただけなのです｡
この場合､ 数値を生成しているのではなく､
リストから返しているのです｡
そこで､ 簡単な例を挙げてみましょう｡
セクションのサンプルコードに追加するのを覚えていれば､
これはあります｡
つまり､ nextメソッドを定義するときに､
イテレータを定義しているのです｡
必ずしもすべての数字を生成する必要はありませんが､ リストから､
あるいは送信されたものから､ あるいは他のどこからでも､
数字を返すことができます｡
だから､ Pythonではそれが重要なんです｡
イテレータとは､ ダンダンnextメソッドを持つオブジェクトのことです｡
次にかけることができます｡
私たち自身はイテレータを持っていますが､
私のゲンでは､
私のゲンでは､ Iのために行うことはできません｡
できません｡
今すぐ教えてあげよう｡
これを実行すると､ 最初の100個のジェネレータオブジェクトは反復可能ではない､
というエラーが出ますが､ 今､ イテレータだと言ったので､
イテレータです｡
イテレータが意味するのは､ その上で次の関数を呼べば､
次の値が得られるということです｡
しかし､ イテレータとイテラブルは別物です｡
イテラブルに対して反復処理を行うことができ､
イテレータはシーケンスから次の値を取得したり､ 生成された値から取得したりするために使用されます｡
つまり､ ここで手に入れたのはイテレータであってイテラブルではありません｡
次のビデオでは､ 反復処理可能なオブジェクトを作成して､
その上でループ処理を行ったり､
sum of my genなどの処理を行ったりする方法を学びます｡
マイゲン一覧
これらはイテレータではなくイテラブルを必要とします｡
では､ 次のビデオでそれをやってみましょう｡
現地でお会いしましょう｡