наследование классов Python для параметров - PullRequest
0 голосов
/ 02 декабря 2011

Я пытаюсь создать класс расписания в Python, который принимает время начала, время окончания и место встречи. Пока что у меня есть:

class Schedule(Time):
def __init__(self, start_time, end_time, location):
    self.start_time = start_time
    self.end_time = end_time
    self.location = location
    print (self.start_time)
    print (self.end_time)
    print (self.location)

У меня закончен класс Time, который выглядит следующим образом:

class Time():
    def __init__(self, init_hr = 12, init_min = 0, init_ampm = "AM"):
        self.hr = init_hr
        self.min = init_min
        self.ampm = init_ampm

Теперь я хочу иметь возможность сделать параметры start_time и end_time (из инициализации расписания) экземплярами Time, однако я не совсем понимаю, как мне поступить. Есть предложения?

Ответы [ 6 ]

2 голосов
/ 02 декабря 2011

Некоторые динамически типизированные языки хотели бы, чтобы вы делали это везде (языки со статической типизацией, как правило, применяют это сами), но в Python обычно рекомендуется использовать утиная типизация , что предполагает, что вы просто ожидаете это время, но если это что-то другое, не беспокойтесь (если он реализует тот же интерфейс, что и время, хорошо, если это не так, дайте сбой при попытке доступа к атрибутам, которые не существуют в предмет). Общая идея заключается в том, что вы должны быть достаточно умны, чтобы знать, что вы делаете.

Если бы я писал этот код, я бы оставил его как есть, с несколькими примечаниями:

  • Как уже упоминалось, измените class Schedule(Time) на class Schedule(object).
  • В Time.__init__ не вызывайте ваши параметры init_hr и т. Д., Просто называйте их hr и т. Д. Python - это не Java, где вы должны использовать разные имена или всегда обращаться к версия класса как this.*. В Python вы всегда используете self.*. У Python также есть ключевые аргументы - так что вы можете иметь Time(hr=4, ...); Time(init_hr=4, ...) было бы некрасиво.
  • Если вы используете Python 2, измените print (...) на print .... Если вы используете Python 3, измените его на print(...).
2 голосов
/ 02 декабря 2011

Вам не нужно ничего менять в своем коде.

Однако вы можете:

  • Задокументировать это, чтобы прояснить ожидаемый тип параметров (Iдля этого рекомендуем sphinx .
  • Напишите утверждения, чтобы убедиться, что передаваемый тип соответствует вашим ожиданиям (assert isinstance(variable, type)).Вы даже можете использовать некоторые дополнительные библиотеки для этого, например pycontracts .
  • Пишите юнит-тесты также, чтобы убедиться, что весь API работает должным образом, то есть принимаются только ожидаемые типы ( unittest библиотека прекрасно работает, но вы можете взглянуть на альтернативных бегунов, таких как nose или pytest ).

Относительно Schedule будучи подклассом Time, я согласен с другими ответами.

2 голосов
/ 02 декабря 2011

Вы, вероятно, не хотите, чтобы Расписание было подклассом Времени; отношения между ними, скорее всего, «имеет», а не «является». Просто сделайте его подклассом object, и все будет в порядке.

1 голос
/ 02 декабря 2011

Вы бы сказали, что "расписание - это время"? Я бы не стал. Это подразумевает, что они не наследуют таким образом. Я бы сказал, что расписание - это коллекция времен, а это значит, что у вашего класса расписания будет атрибут, который представляет собой список времен.

0 голосов
/ 02 декабря 2011

Как правило, в Python рекомендуется обращаться с ним как с объектом Time и просто проверять, есть ли у него нужные свойства, а не с помощью isinstance. Таким образом, кто-то (включая вас) может в будущем создать свой собственный Time -подобный объект с соответствующими атрибутами (hr, min, ampm) и использовать его в качестве замены. Это даже сработало бы - если вы не выполняете основную логику с объектами Time или взаимодействуете с этой логикой с помощью операторов - с их собственными пользовательскими объектами, которые не используют те же поля. Это будет иметь несколько хороших преимуществ, в зависимости от того, как именно работают объекты расписания.

Этот стиль кодирования известен как " Проще просить прощения, чем разрешения " и относительно распространен в python благодаря широкому использованию duck typing .

Несколько лучший шаблон, чем использование isinstance, который все же позволяет вам проверить, соответствует ли он стандарту (если вы хотите это сделать), может вместо этого использовать hasattr. Например:

hasattr(start_time, 'ampm')

Я также согласен с остальными, что Schedule, похоже, не имеет , это отношение с Time, а имеет отношение , иначе Вы можете в конечном итоге создать расписание с Schedule в качестве времени начала и Schedule в качестве времени окончания.

0 голосов
/ 02 декабря 2011

Поскольку в Python тип не может быть проверен во время компиляции, вам нужно написать что-то вроде этого в __init__ из расписания

if not isinstance(start_time, Time):
     raise ValueError("Start time need to be of type time")

или

assert isinstance(start_time, Time)

Аналогично для end_time также

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