Использование «self» в классе python

#python #concept

#python #концепция

Вопрос:

Я изучаю классы на python и выполняю небольшое упражнение. Здесь я создал класс «Progression» и у меня возникли проблемы с методом print_progression. Я понял ошибку типа, которую я получал, но не понял решения. Решение состояло в том, чтобы передать self следующему методу. Итак, основываясь на решении, я должен сделать вывод, что self имеет тип «iter».

 class Progression:
  """ Iterator producing a generic progression.
  Default progresssion : 0,1,2 """

  def __init__(self, start=0):
    self._current = start
  
  def _advance(self):
    """ This should be overridden by a subclass to customize progression """
    self._current  = 1
    return self._current
  
  def __next__(self):
    if self._current == None:
      raise StopIteration()
    else:
      return self._advance()

  def __iter__(self):
    return self._current

  def print_progression(self,values_to_print):
    if self._current != None:
      print(type(self))
      # print(isinstance(self, iter)) # TypeError: isinstance() arg 2 must be a type or tuple of types
      print(" ".join(str(next(self._current)) for i in range(0,values_to_print)))
    
  

Создание экземпляра класса

 p = Progression(start=1)
p.print_progression(3)
  

Ошибка

  <class '__main__.Progression'>
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-83-19a69bdc9721> in <module>()
      1 p = Progression(start=1)
----> 2 p.print_progression(3)

1 frames
<ipython-input-81-f0653f30c8f0> in print_progression(self, values_to_print)
     25       print(type(self))
     26       # print(isinstance(self, iter)) # TypeError: isinstance() arg 2 must be a type or tuple of types
---> 27       print(" ".join(str(next(self._current)) for i in range(0,values_to_print)))
     28 

<ipython-input-81-f0653f30c8f0> in <genexpr>(.0)
     25       print(type(self))
     26       # print(isinstance(self, iter)) # TypeError: isinstance() arg 2 must be a type or tuple of types
---> 27       print(" ".join(str(next(self._current)) for i in range(0,values_to_print)))
     28 

TypeError: 'int' object is not an iterator
  

Я обнаружил, что self._current является типом int и не должен передаваться следующему методу. Вместо этого я должен просто передать self следующему методу, и он работает правильно.

 class Progression:
  """ Iterator producing a generic progression.
  Default progresssion : 0,1,2 """

  def __init__(self, start=0):
    self._current = start
  
  def _advance(self):
    """ This should be overridden by a subclass to customize progression """
    self._current  = 1
    return self._current
  
  def __next__(self):
    if self._current == None:
      raise StopIteration()
    else:
      return self._advance()

  def __iter__(self):
    return self._current

  def print_progression(self,values_to_print):
    if self._current != None:
      print(type(self))
      # print(isinstance(self, iter)) # TypeError: isinstance() arg 2 must be a type or tuple of types
      print(" ".join(str(next(self)) for i in range(0,values_to_print)))
    
  

Комментарии:

1. изменить str(next(self._current) на str(self._current 1)

Ответ №1:

причина в том, что __iter__ это то, что вызывается, когда вы пытаетесь выполнить итерацию по экземпляру вашего пользовательского класса. Вот почему, когда вы выполняете итерацию по своему классу, это работает нормально, потому что ваш класс повторяется до тех пор, пока вы реализовали __iter__ функцию.

итерации возвращают последовательный подсчет, потому что для каждой next функции фактически вызывается ваша пользовательская __next__ функция, которая по мере реализации вызывает self._advance() предшествующую self._current (опять же, переменную, которая возвращается __iter__ ).).

надеюсь, это объяснение имеет смысл для вас.