python - 如何使类对象可迭代
问题描述
我有以下点类:
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”类型的非迭代器。关于如何正确执行此操作的任何想法?
解决方案
tl;博士:
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
)
您可以通过从 each 中创建一个可迭代对象来解决最后一组问题int
,例如单元素列表,迭代该可迭代对象,然后使用yield from
而不是委托给它return
。在函数中使用yield
oryield 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])
最后,与其依赖生成器、列表迭代器chain
或 Python 附带的其他迭代器类型,您始终可以显式编写一个:
class PointIterator:
def __init__(self, point):
self.values = [point.x, point.y]
def __next__(self):
try:
return self.values.pop(0)
except IndexError:
raise StopIteration
def __iter__(self):
return self
class Point:
# ... other code
def __iter__(self):
return PointIterator(self)
推荐阅读
- python - 下载文件时如何向下滚动页面以避免错误
- ruby-on-rails - BCrypt InvalidHash 清除密码重置
- python - 有没有办法打印在 __init__ 方法中创建的对象的所有参数?
- java - 转换不带双括号的引用变量
- javascript - 摩纳哥编辑器 AddComment 事件触发两次
- python-3.x - 根据拼写清理列?熊猫
- algorithm - 优化算法:从列表数组中查找最近的列表
- r - R - 如何同时取消列出和连接
- r - 使用 lme4 包对随机效应组件进行建模
- c# - 通过公共 IP 访问 SSH 隧道 IIS“错误请求 - 无效主机名”