Несоответствие наследования - PullRequest
0 голосов
/ 18 ноября 2018

Возникли проблемы с решением проблемы наследования в 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.

Чтобы обработать високосные годы, я хочу назначить две разные переменные для месяцев и дней в месяце (months_norm, months_leap, length_norm, length_leap), которые указаны в подклассе календаря, в этом случае Shire_Calendar, а затем функция _is_leap_year в суперклассе считывает ввод года, определяет, является ли он високосным, и назначает соответствующий кортеж месяца и дни в кортеже месяца общим переменным months и length. Оттуда общие переменные передаются в функцию day_of_year_to_date.

Проблема в том, что когда я пытаюсь передать эти переменные, он выдает ошибку имени, что Shire_Calendar не имеет атрибута length. Как будто внутри функции _is_leap_year months и length не присваиваются или назначаются не в том месте.

1 Ответ

0 голосов
/ 18 ноября 2018

Когда вы вызываете 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,поэтому его не существует, когда вы пытаетесь его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...