目的

2017-04-12 8 views
-1

は私がに問題が持っている「私はすでにこの質問を見てきました目的

class Fib: 
def __init__(self, max): 
    self.max = max 
def __iter__(self): 
    self.a = 0 
    self.b = 1 
    return self 
def __next__(self): 
    fib = self.a 
    if fib > self.max: 
     raise StopIteration 
    self.a, self.b = self.b, self.a + self.b 
    return fib 

戻りself'.`をreturn self problemが、私はの利点であるかを理解することはできません」

「自己を返すが、

私は

+0

は利益を定義? –

+0

[ドキュメントの '' __iter__'](https://docs.python.org/3/reference/datamodel.html#object.__iter__)あなたはそこから読むことができます。短い答え: '__iter__'はイテレータに必要なので' self'を返します。 – Matthias

+0

@Elliot Roberts何を使用していますか? – AmrElgendy

答えて

1

これは、すべてのように表現する方がはるかに簡単です

class Fib: 

    """Implements the Fibonacci sequence.""" 

    def __init__(self, max_): 
     self.max = max_ 

    def __iter__(self): 
     """Initializes and returns itself as an iterable.""" 

     self.a = 0 
     self.b = 1 
     return self 

    def __next__(self): 
     """What gets run on each execution of that iterable.""" 

     fib = self.a 
     if fib > self.max: 
      raise StopIteration 
     self.a, self.b = self.b, self.a + self.b # increment 
     return fib 

:何それがないことはこれです言​​われていること

、メソッドとは、メソッドが呼び出されたインスタンスオブジェクトへの参照を返すことを意味します。これは、method cascadingを奨励するfluent interfaceとして設計されたオブジェクト指向のAPIで使用されることがあります。したがって、たとえば、

>>> class Counter(object): 
...  def __init__(self, start=1): 
...   self.val = start 
...  def increment(self): 
...   self.val += 1 
...   return self 
...  def decrement(self): 
...   self.val -= 1 
...   return self 
... 
>>> c = Counter() 

今、私たちは、メソッドのカスケード使用することができます。

>>> c.increment().increment().decrement() 
<__main__.Counter object at 0x1020c1390> 

お知らせを、decrement()への最後の呼び出しはselfである、<__main__.Counter object at 0x1020c1390>を返しました。 は今:あなたがselfを返さなかった場合

>>> c.val 
2 
>>> 

お知らせ、あなたがこれを行うことはできません。

>>> class Counter(object): 
...  def __init__(self, start=1): 
...   self.val = start 
...  def increment(self): 
...   self.val += 1 
...   # implicitely return `None` 
...  def decrement(self): 
...   self.val -= 1 
...   # implicitely return `None` 
... 
>>> c = Counter() 
>>> c.increment().increment() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'NoneType' object has no attribute 'increment' 
>>> c 
<__main__.Counter object at 0x1020c15f8> 
>>> c.val 
2 
>>> 

お知らせ、誰もが「方法カスケード」のデザインのファンです。 Pythonの組み込み関数は、これを行う傾向があるので、例えばlistません:

>>> x = list() 
>>> x.append(1).append(2) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'NoneType' object has no attribute 'append' 
>>> 

あなたはは、多くの場合、あなたのクラスは、イテレータのiterselfによってを返すiteratorプロトコルを実装したときにこれは見ない1位大会は、これはthe docsによって提案されたものの:

イテレータプロトコルの背後にある仕組みを見た、あなたのクラスにイテレータの振る舞いを追加 に簡単です。 __iter__()メソッド を定義し、__next__()メソッドを持つオブジェクトを返します。クラス は__next__()を定義する場合は、__iter__()だけselfを返すことができます。

class Reverse: 
    """Iterator for looping over a sequence backwards.""" 
    def __init__(self, data): 
     self.data = data 
     self.index = len(data) 

    def __iter__(self): 
     return self 

    def __next__(self): 
     if self.index == 0: 
      raise StopIteration 
     self.index = self.index - 1 
     return self.data[self.index] 

お知らせを、効果で、これは単一のパスのためのあなたのイテレータはのみ有用になる:

>>> x = [1, 2, 3, 4] 
>>> it = iter(x) 
>>> list(it) 
[1, 2, 3, 4] 
>>> list(it) 
[] 
>>> next(it) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 
>>> 
+0

ありがとう、良い説明 – AmrElgendy

+0

@AmrElgendyよろしくお願いします。最後にもう少し情報を追加しましたので、最新の編集をチェックしてください。 –

1

少し英語を話すので、これは不複雑なコードで単純な答えを必要としてください。それにほとんど注意を払わないでください。地球上にこのように実装する理由はありません。

def fib(max_): 
    a, b = 0, 1 
    while b <= max_: 
     out = a 
     a, b = b, a+b 
     yield out 

例:Aからselfを返す

>>> fib_obj = Fib(20) 
>>> for n in fib_obj: 
...  print(n) 

>>> for n in Fib(20): 
...  print(n) 

>>> for n in fib(20): 
...  print(n) 
# all give.... 
0 
1 
1 
2 
3 
5 
8 
13 
+0

その意味は 'self.a = 0 self.b = 1'です。 – AmrElgendy

+0

@AmrElgendy '__iter__'はイテレータ(つまり' __next__'メソッドを持つオブジェクト)を初期化するために一度実行され、 'self.a'と' self.b'は '__next__'メソッドで使われます。これは、オブジェクトを実装するための愚かな方法です。 –

+0

申し訳ありませんが、これは最後の質問です 私が理解していることは、 '__next__'からそれを呼び出すときに' __iter__'が一度実装されていることです。 – AmrElgendy