如何使类对象可迭代

时间:2018-08-18 19:20:15

标签: python python-3.x

我有以下分数班:

import math

class Point:
    """Two-Dimensional Point(x, y)"""
    def __init__(self, x=0, y=0):
        # Initialize the Point instance
        self.x = x
        self.y = y

   # def __iter__(self):
 #       return iter(int(self.x))
 #       return iter(int(self.y))
        return self

    @property
    def magnitude(self):
        # """Return the magnitude of vector from (0,0) to self."""
        return math.sqrt(self.x ** 2 + self.y ** 2)


    def distance(self, self2):
         return math.sqrt((self2.x - self.x) ** 2 + (self2.y - self.y) ** 2)

    def __str__(self):
        return 'Point at ({}, {})'.format(self.x, self.y)

    def __repr__(self):
        return "Point(x={},y={})".format(self.x, self.y)

我想使“点”变得可迭代,以便可以进行以下操作:

point = Point(2, 3)
x, y = point
print(x)
    2
print(y)
    3

如果您看到我的注释代码,那是我尝试的方法,但是它显示TypeError:iter()返回了类型为“ Point”的非迭代器。有关如何正确执行此操作的任何想法?

4 个答案:

答案 0 :(得分:4)

tl; dr:

def __iter__(self):
    yield self.x
    yield self.y

要使其具有可迭代性,您需要使用__iter__方法来返回迭代器。

除非return self已经是迭代器(这意味着它具有self方法),否则您不能仅仅__next__。但是您不希望points成为迭代器,而是希望它可以反复迭代。

您不能return iter(int(self.x)),然后return iter(int(self.y)),有两个原因。首先,在完成return之后,您的功能就完成了;此后发生的任何代码都永远不会运行。其次,您无法在iter上呼叫int。 (而且,没有理由在int上调用int。)


您可以通过在每个int中创建一个可迭代对象(如单元素列表),迭代该可迭代对象,然后使用yield from而不是{{ 1}}。在函数中使用returnyield使其成为生成器函数,并且由生成的函数创建的生成器为迭代器:

yield from

…但是这有点愚蠢。一旦知道要使用生成器,就可以yield from iter([self.x]) yield from iter([self.y]) 迭代我们想要的值。因此,代码位于顶部。


或者,您可以为两个元素显式创建一个单元素可迭代对象,并将它们链接在一起并返回:

yield

但这也很愚蠢。在单元素列表上链接两个迭代器与仅对两个元素列表进行迭代相同:

def __iter__(self):
    return itertools.chain(iter([self.x]), iter([self.y]))

最后,您不必依赖于生成器,列表迭代器,def __iter__(self): return iter([self.x, self.y]) 或Python附带的其他迭代器类型,而总是可以显式地编写一个:

chain

答案 1 :(得分:2)

您可以使用yield

class Point:
  def __init__(self, x=0, y=0):
    self.x = x
    self.y = y
  def __iter__(self):
    yield self.x
    yield self.y

a, b = Point(4, 5)
print([a, b])

输出:

[4, 5]

答案 2 :(得分:1)

您应该实现一个特殊的__iter__(self)方法,该方法应返回一个 iterator 。添加类似

def __iter__(self):
    return iter([self.x, self.y])

答案 3 :(得分:1)

您的__iter__方法应产生x和y值

def __iter__(self):
    yield self.x
    yield self.y

这样,您将获得以下输出

>>> point = Point(2, 3)
>>> x, y = point
>>> print (x)
2
>>> print (y)
3
>>>