继承不一致

时间:2018-11-17 22:46:34

标签: python inheritance

在Python中解决继承问题时遇到一些麻烦。我的代码是:

class Calendar(object):
    def __init__(self):
        self.norm_year = (365)
        self.leap_year = (366)

    def _input_validity(self, args_num, *args):
        if len(args) != args_num: 
            return False
        elif len(args) == 3:  
            args[0] = month
            args[1] = day
            args[2] = year
            if type(month) != str or type(day) != int or type(year) != int:
                return False
        elif len(args) == 2:
            args[0] = year
            args[1] = doy
            if type(year) != int or type(doy) != int:
                return False

    def _is_leap_year(self, year):
        print(str(self))
        if (type(year) != int) or (year <= 0):
            return
        if (year % 4 == 0):
            if (year % 400 == 0) or (year % 100 != 0):
                self.days_in_year = self.leap_year
                self.months = self.months_leap
                self.length = self.length_leap
                return True
            else:
                self.days_in_year = self.norm_year
                self.months = self.months_norm
                self.length = self.length_norm
                return False
        else:
            self.days_in_year = self.norm_year
            self.months = self.months_norm
            self.length = self.length_norm
            return False



    def date_to_day_of_year(self, *args):

        pass

    def day_of_year_to_date(self, *args):
        args_num = 2
        year = args[0]
        doy = args[1]
        self._is_leap_year(year)
        if self._input_validity == False:
            return
        else:
            month = 1
            for i in self.length:
                if doy > i:
                    month += 1
                    doy -= i
                elif doy <= i:
                    day = doy
                    month = self.months[month]
                    return(str(month), day, year)

    def date_to_day_of_week(self, *args):
        # This can be called with three arguments such as
        #   obj.date_to_day_of_year("Messidor", 14, 1789)
        # or with two arguments such as
        #   obj.date_to_day_of_year("Midyear"s Day", 1418)
        # You need to determine which by looking at len(args).

        pass

class Gregorian_Calendar(Calendar):
    def __init__(self):
        super().__init__()
        self.months_norm = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}
        self.months_leap = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'}
        self.length_norm = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
        self.length_leap = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
        self.weekdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri') 

    def day_of_year_to_day_of_week(self, year, doy):
        pass

class Shire_Calendar(Calendar):
    def __init__(self):
        super().__init__()
        self.months_norm = {1: "2 Yule", 2: "Afteryule", 3: "Solmath", 4: "Rethe", 5: "Astron", 6: "Thrimidge", 7: "Forelithe", 8: "1 Lithe", 9: "Midyear's Day", 10: "2 Lithe", 11: "Afterlithe", 12: "Wedmath", 13: "Halimath", 14: "Winterfilth", 15: "Blotmath", 16: "Foreyule", 17: "1 Yule"}
        self.months_leap = {1: "2 Yule", 2: "Afteryule", 3: "Solmath", 4: "Rethe", 5: "Astron", 6: "Thrimidge", 7: "Forelithe", 8: "1 Lithe", 9: "Midyear's Day", 10: "Overlithe", 11: "2 Lithe", 12: "Afterlithe", 13: "Wedmath", 14: "Halimath", 15: "Winterfilth", 16: "Blotmath", 17: "Foreyule", 18: "1 Yule"}
        self.length_norm = (1, 30, 30, 30, 30, 30, 30, 1, 1, 1, 1, 30, 30, 30, 30, 30, 30, 1)
        self.length_leap = (1, 30, 30, 30, 30, 30, 30, 1, 1, 1, 30, 30, 30, 30, 30, 30, 1)
        self.weekdays = ("Sterday", "Sunday", "Monday", "Trewsday", "Hensday", "Mersday", "Highday")

    def _is_leap_year(self, year):
        if (year % 4 == 0) and (year % 100 != 0):
            self.days_in_year = self.leap_year
            return True
        else:
            self.days_in_year = self.norm_year
            return False


    def day_of_year_to_day_of_week(self, year, doy):
        pass

class Calendrier_Républicain(Calendar):
    def __init__(self):
        super().__init__()
        self.months_norm = {"Vendémiaire": 1, "Brumaire": 2, "Frimaire": 3, "Nivôse": 4, "Pluviôse": 5, "Ventôse": 6, "Germinal": 7, "Floréal": 8, "Prairial": 9, "Messidor": 10, "Thermidor": 11, "Fructidor": 12, "Jour de la vertu": 13, "Jour du génie": 14, "Jour du travail": 15, "Jour de l'opinion": 16, "Jour des récompenses": 17}
        self.months = {"Vendémiaire": 1, "Brumaire": 2, "Frimaire": 3, "Nivôse": 4, "Pluviôse": 5, "Ventôse": 6, "Germinal": 7, "Floréal": 8, "Prairial": 9, "Messidor": 10, "Thermidor": 11, "Fructidor": 12, "Jour de la vertu": 13, "Jour du génie": 14, "Jour du travail": 15, "Jour de l'opinion": 16, "Jour des récompenses": 17, "Jour de la Révolution": 18}
        self.length_norm = (30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 1, 1, 1, 1, 1)
        self.length_leap = (30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 1, 1, 1, 1, 1, 1)
        self.weekdays = ("primidi", "duodi", "tridi", "quartidi", "quintidi", "sextidi", "septidi", "octidi", "nonidi", "décadi")

    def day_of_year_to_day_of_week(self, year, doy):
        pass




# Basic Testing
cal = Calendar()
gcal = Gregorian_Calendar()
scal = Shire_Calendar()
rcal = Calendrier_Républicain()

print(scal.day_of_year_to_date(1400, 2))
print(scal.day_of_year_to_date(1400, 184))
print(scal.day_of_year_to_date(1404, 184))

我正在尝试创建一个超类,该超类将能够处理多种不同类型的日历并对其执行操作。我显示的示例是超类中的一个函数,该函数通过使用Shire_Calendar子类中的信息将一年中的某天转换为日期。

为了处理leap年,我想为一个月的月份和天分配两个不同的变量(months_normmonths_leaplength_normlength_leap),在日历子类(在这种情况下为Shire_Calendar中指定的值)中,然后超类中的_is_leap_year函数读取年份输入,确定是否为a年,并分配适当的月份元组和日期在一个月的元组中到达常规变量monthslength。从那里,将常规变量传递到函数day_of_year_to_date

问题在于,当我尝试传递这些变量时,它吐出了一个名称错误,即Shire_Calendar没有属性length。就像在_is_leap_year函数中一样,monthslength没有被分配,或者没有被分配到错误的位置。

1 个答案:

答案 0 :(得分:1)

调用scal.day_of_year_to_date(1400, 2)时,将调用day_of_year_to_date()中定义的Calendar方法。

在父类的此方法中,您正在调用self._is_leap_year(year)。由于您的实例是Shire_Calendar,因此将调用self._is_leap_year()中定义的Shire_Calendar

但是与基类的_is_leap_year()方法相反,此方法未设置self.length,因此在尝试使用它时不存在。