【问题标题】:using __iter__ and __next__ to create my own class使用 __iter__ 和 __next__ 创建我自己的类
【发布时间】:2020-10-30 04:26:35
【问题描述】:

我正在尝试为迭代器创建自己的类并找到了这样一个示例:

class OddNum:
  """Class to implement iterator protocol"""

  def __init__(self, num = 0):
    self.num = num

  def __iter__(self):
    self.x = 1
    return self

  def __next__(self):
    if self.x <= self.num:
      odd_num = self.x
      self.x += 2
      return odd_num
    else:
      raise StopIteration

for num in OddNum(10):
  print(num)

输出为:1 3 5 7 9

现在,如果我删除行 odd_num = self.x 并将 return odd_num 更改为 return self.x,我会得到以下输出:3 5 7 9 11

这2个代码有什么区别,为什么要定义一个变量为self.x

【问题讨论】:

  • 您在添加 2 之后而不是之前获取 self.x 的值。所以差是2。
  • 在您有机会返回初始值之前增加self.x
  • 如果你想这样做,初始化self.x = -1,让self.x += 2产生第一个奇数。
  • 我赞成,因为这个问题已明确说明并遵循网站规则,无论其复杂性如何。有人会认为这是最低限度的要求,但现在它在初学者中变得如此罕见,我认为应该特别鼓励它。干得好,欢迎来到!

标签: python class iterator next


【解决方案1】:

在这种特定情况下,发生的情况是,在为下一次迭代准备好 self.x 的值递增之前,您希望从 __next__ 方法中间的某个位置返回 self.x 的值。因此变量odd_num 用于保存该值。相反,如果您在 self.x += 2 语句之后返回 self.x(即添加 2),那么您将得到不同的答案,如您所见。

您可以考虑的另一种可能性是,如果您想要使用代码中间某处某个变量的值,而不是编写自己的类,而是使用生成器函数来实现迭代器。这是因为您可以将yield 声明放在您喜欢的任何位置。所以在这个例子中,它看起来像这样:

def odd_num(num=0):
    x = 1
    while x <= num:
        yield x
        x += 2
  
    
for num in odd_num(10):
    print(num)

这给出了:

1
3
5
7
9

(注意while 代替了您在__next__ 方法中使用的if。)

这里,yield 语句在 x += 2 语句之前,这不是使用方法(函数)中的return 可以完成的。所以不需要将值保存在另一个变量中以供以后使用。

【讨论】:

  • 当我更新我的答案时,我不知道你发布了。删除了我几乎相同的答案。干得好。
  • @MadPhysicist 顺便说一句,不要觉得你删除你的答案。鉴于时间非常接近,没有人可以合理地指责您只是抄袭我写的内容。
  • 我删除了它,因为我们的内容几乎相同,我觉得我们中的一个人应该这样做,而且我碰巧更喜欢你的措辞。
  • 非常感谢您的详细解释。我这边的另一个问题:在我的示例中,为什么 self.x = 1 在 iter 函数中给出?为什么不在外部(例如作为类对象属性或在下一个函数中的 if 语句之前)?
  • @rodny9 关键是您可以从类中多次生成迭代器。尝试在调用代码中执行以下操作:nums = OddNum(10),然后是 for n in nums: print(n),然后再次:for n in nums: print(n)——它会起作用,因为在执行 for 语句时会调用 nums.__iter__ 来生成迭代器。现在尝试将self.x = 1 移动到__init__ 而不是__iter__ 中,您应该会看到您可以迭代一次,但是第二次尝试迭代时,迭代器已经用尽,您不会再得到任何值了.
猜你喜欢
  • 2019-02-02
  • 2021-04-02
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-09
相关资源
最近更新 更多