Строка 60, в make_tuple return tuple (l) TypeError: iter() возвращен неитератор типа 'Vector'

Я новичок в Vectors и делаю классы. Я пытаюсь построить свой собственный векторный класс, но когда я передаю его через свой код, который:

позиция + = заголовок * distance_moved

где позиция и заголовок - оба вектора. курс нормализуется. моя цель - повторить мой код до позиции = пункт назначения. Что не так с этим классом?

import math

class Vector(object):
    #defaults are set at 0.0 for x and y
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y

    #allows us to return a string for print
    def __str__(self):
        return "(%s, %s)"%(self.x, self.y)

    # from_points generates a vector between 2 pairs of (x,y) coordinates
    @classmethod
    def from_points(cls, P1, P2):
        return cls(P2[0] - P1[0], P2[1] - P1[1])

    #calculate magnitude(distance of the line from points a to points b
    def get_magnitude(self):
        return math.sqrt(self.x**2+self.y**2)

    #normalizes the vector (divides it by a magnitude and finds the direction)
    def normalize(self):
        magnitude = self.get_magnitude()
        self.x/= magnitude
        self.y/= magnitude

    #adds two vectors and returns the results(a new line from start of line ab to end of line bc)
    def __add__(self, rhs):
        return Vector(self.x +rhs.x, self.y+rhs.y)

    #subtracts two vectors
    def __sub__(self, rhs):
        return Vector(self.x - rhs.x, self.y-rhs.y)

    #negates or returns a vector back in the opposite direction
    def __neg__(self):
        return Vector(-self.x, -self.y)

    #multiply the vector (scales its size) multiplying by negative reverses the direction
    def __mul__(self, scalar):
        return Vector(self.x*scalar, self.y*scalar)

    #divides the vector (scales its size down)
    def __div__(self, scalar):
        return Vector(self.x/scalar, self.y/scalar)

    #iterator
    def __iter__(self):
        return self

    #next
    def next(self):
        self.current += 1
        return self.current - 1

    #turns a list into a tuple
    def make_tuple(l):
        return tuple(l)

Ответ 1

Я предполагаю, что вы используете python 3.x, потому что у меня есть аналогичная ошибка. Я также новичок в создании класса, но было бы неплохо поделиться тем, что я узнал:)

В 3.x используйте __next__() вместо next() в определении классов. Ошибка не произошла после того, как я переименовал ее в свой код, но у меня возникла другая проблема: "Объект" Вектор "не имеет атрибута" current "::

Я думаю, вам было бы лучше понять итераторы (и класс?) больше. Самый простой пример:

class Count:
    def __init__(self, n):
        self.max = n

    def __iter__(self):
        self.count = 0
        return self

    def __next__(self):
        if self.count == self.max:
            raise StopIteration
        self.count += 1
        return self.count - 1

if __name__ == '__main__':
    c = Count(4)
    for i in c:
        print(i, end = ',')

а выходы - 0,1,2,3,.

С векторным классом я хочу перебрать компоненты вектора. Итак:

def __iter__(self):
    self.count = 0
    self.list = [self.x, self.y, self.z]  # for three dimension
    return self

def __next__(self):
    if self.count == len(self.list):
        raise StopIteration
    self.count += 1
    return self.list[self.count - 1]

и итератор выводит последовательность x, y, z.

Обратите внимание, что наиболее важной особенностью итераторов является последовательная последовательность действий без создания цельного списка. Поэтому не очень хорошая идея сделать self.list, если последовательность будет очень длинной. Подробнее здесь: учебник python

Ответ 2

Первым аргументом, который передается в make_tuple, является ваш экземпляр Vector (это тот же аргумент self, который вы помещаете повсюду).

Вы должны передать то, что хотите превратить в кортеж, который, вероятно, является вашими координатами x и y:

def make_tuple(self):
    return (self.x, self.y)