何も誇れぬ人生の記録

『ぼくは何も誇れないのが誇りだな』沼田真佑、影裏より

クラスについて

# 継承
class HelloForEver:
  def readline(self): # 自分自身selfが必須
    return 'Hello.\n'

class HelloFile(HelloForEver):
  def __init__(self, n):
    self.n = n
  def readline(self):
    if self.n == 0:
      return ''
    self.n = self.n - 1
    return super().readline()
'''
Example:
f = HelloFile(3)
f.readline()
Out: 'Hello.\n'
'''

# 特殊メソッド (__init__, __iter__, __next__)
class HelloFileIterator(HelloFile):
  def __iter__(self):
    return self
  def __next__(self):
    line = self.readline()
    if line == '':
      raise StopIteration
    return line


f = HelloFileIterator(3)
print(f is iter(f)) # オブジェクトとして完全に同一
#Out: True
for line in f:
  print(line)
'''
Out:
Hello.

Hello.

Hello.
'''
class EmptyFile(HelloFileIterator):
    def readline(self):
        return ''

f = EmptyFile(3)
next(f)
#Out: StopIteration

# with文への対応
class HelloFileIterator(HelloFile):
    def __enter__(self):
        return self
    def __exit__(self,exception_type,exception_value,traceback):
        pass
    def __next__(self):
        line = self.readline()
        if line == '':
            raise StopIteration
        return line
    def __iter__(self):
        return self

with HelloFileIterator(3) as f: # メソッドを使い終えたら消える
    for line in f:
        print(line)
'''
'Hello.\n' ではなくて、
初期時に指定された文字列を繰り返し返すように、 
新たなクラス StringFileIterator を定義してください。
'''
# 解答
class StringFileIterator:
  def __init__(self, s, n):
    self.s = s
    self.n = n
  def __iter__(self):
    return self
  def __next__(self):
    if not self.n: # sefl.n != 0 で偽
      raise StopIteration
    else:
      self.n -= 1
      return self.s

# 模範解答
'''
class HelloFileIterator(HelloFile):
  def __iter__(self):
    return self
  def __next__(self):
    line = self.readline()
    if line == '':
      raise StopIteration
    return line
'''
class StringFileIterator(HelloFileIterator):
    def __init__(self, s, n):
        self.s = s
        self.n = n
    def readline(self):
        if self.n == 0:
            return ''
        self.n = self.n - 1
        return self.s
  
f = StringFileIterator('abc', 3)
print(list(f) == ['abc','abc','abc'])