我有以下分数班:
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”的非迭代器。有关如何正确执行此操作的任何想法?
答案 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}}。在函数中使用return
或yield
使其成为生成器函数,并且由生成的函数创建的生成器为迭代器:
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
>>>