Peteryo01223 发表于 2021-3-30 14:29:59

第48课:迭代器,闰年判定

原题:写一个迭代器,要求输出至今为止的所有闰年。
标准答案:
import datetime as dt

class LeapYear:
    def __init__(self):
      self.now = dt.date.today().year

    def isLeapYear(self, year):
      if (year%4 == 0 and year%100 != 0) or (year%400 == 0):
            return True
      else:
            return False

    def __iter__(self):
      return self

    def __next__(self):
      while not self.isLeapYear(self.now):
            self.now -= 1

      temp = self.now
      self.now -= 1

      return temp
问题:
1. 第5句里,today后面为何有个()?
2. 第16-18句,为何要定义 __next__?这个魔法方法,不是 Python 自带的么?
3. 第20句,self.now 直接赋值给 temp, 是怎么知道self.now 符合条件的?
4. 第21句,为何要重复一遍 self.now -= 1?
谢谢~ 看到好答案,保证迅速给“最佳”

昨非 发表于 2021-3-30 17:43:03

1、today是一个方法(函数),调用的时候要加括号
2、这是自定义类对__next__的重写,有自己设置的“规则”,比如这里的闰年判断
3、      while not self.isLeapYear(self.now):
            self.now -= 1

      temp = self.now
      self.now -= 1
while表示不是闰年的那一个分支,只有当while不成立时,才会执行      temp = self.now,所以是符合条件的

4、还是上面那四行,不管是否为闰年,没执行一次next,都必须now-1,最后加的这一行-1,就是为了满足所有未进入while的分支中也要now-1

Peteryo01223 发表于 2021-3-30 18:01:45

昨非 发表于 2021-3-30 17:43
1、today是一个方法(函数),调用的时候要加括号
2、这是自定义类对__next__的重写,有自己设置的“规则 ...

谢谢!

jackz007 发表于 2021-3-30 19:01:32

本帖最后由 jackz007 于 2021-3-30 19:18 编辑

       我估计关键的问题是,你不知道应该如何使用这个类,给你一个实例,有了实例就好理解多了。
       此外,这个类定义有缺陷,__next__() 会无限循环,没有终点。
import datetime as dt

class LeapYear:
    def __init__(self , end = 0):      # 添加新的类属性 end,用于确定迭代终点,如果缺省,那就一直迭代到公元 0 年
      self.now = dt.date.today().year
      self.end = end                   # 为新属性赋值

    def isLeapYear(self, year):
      if (year%4 == 0 and year%100 != 0) or (year%400 == 0):
            return True
      else:
            return False

    def __iter__(self):
      return self

    def __next__(self):

      while not self.isLeapYear(self.now) and self.now > 0:
            self.now -= 1
      if self.now >= self.end:         # 如果没有到达迭代终点
            temp = self.now
            self.now -= 1
            return temp
      else:                            # 否则
            raise StopIteration()      # 终结迭代器
for x in LeapYear(1900):
    print(x)
      运行实况
D:\0002.Exercise\Python>python x.py
2020
2016
2012
2008
2004
2000
1996
1992
1988
1984
1980
1976
1972
1968
1964
1960
1956
1952
1948
1944
1940
1936
1932
1928
1924
1920
1916
1912
1908
1904

D:\0002.Exercise\Python>

Peteryo01223 发表于 2021-3-31 08:25:37

jackz007 发表于 2021-3-30 19:01
我估计关键的问题是,你不知道应该如何使用这个类,给你一个实例,有了实例就好理解多了。
      ...

太好了,谢谢!
页: [1]
查看完整版本: 第48课:迭代器,闰年判定