Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@helloworld2

イテラブルなクラス

More than 1 year has passed since last update.

pythonのイテレータって、結構重宝する機能な気がして個人的には好きなんですが、
バージョン毎に挙動が違ってちょっとややこしい。

↑こちらの記事にたどり着いてスッキリしました。

python3.7におけるイテラブルなクラス

class A(object):
    def __init__(self):
        self.no_list = [1, 2, 3]
    def __iter__(self):
        for no in self.no_list:
            yield no
        else:
            return

a = A()

for no in a:
    print(no)

for no in a:
    print(no)

■実行結果
1
2
3
1
2
3

イテレータは、対象を配列のように扱えるようにします。
クラスにイテレータを実装すると、クラス変数はまるで配列であるかのように
for in 構文を使えます。
二回実行しても、イテレータはちゃんとリセットされてるので、
また配列の先頭から処理されます。

python3.6系以前

class A(object):
    def __init__(self):
        self.no_list = [1, 2, 3]
    def __iter__(self):
        for no in self.no_list:
            yield no
        else:
            raise stopIteration()

3.6系以前だとこんな感じ。配列の終端を例外で通知していた。
例外を柔軟に使ってて、これはこれで良い気がするんだけど、
3.7系でこれをやると配列の終端に達した時に、本当に例外がアプリコードへスローされます。

RuntimeError: generator raised StopIteration

つまり、for in 構文の外側でtry/exceptしないといけません。
せっかくクラス変数が配列のように直感的に扱えるようになるのに、これでは台無しです。
ということでpython3.7系では最初のように記述するのが正解です。

python3.7系では、例外は例外なくアプリへスローすべき、というポリシーになったんでしょうか。
個人的には3.6系以前の柔軟な例外の使い方も好きなんですが・・・

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?