2014-12-02 3 views
1

Привет всем, у меня есть класс, который работает со временем, например, вы вводите два раза, и можете их суммировать (на данный момент не имеет значения, что это выходит за пределы 23:59:59) или умножить их и т. д. Значением по умолчанию являются нули. Существует также функция, которая возвращает текущее время. Я могу позвонить time = Time(), который возвращает 0:00:00, time = Time(12) возвращает 12:00:00.Принять одну строку вместо обычных параметров

Проблема, что у меня есть, я хочу назвать time = Time('now') и он должен хранить там текущее время с помощью функции now(), редактирование должно быть сделано в __init__() (если вам не нравится now() вы можете изменить его). Но если я положил time_now = '' в качестве первого параметра, это не сработает, то же самое, когда я ставлю его последним, потому что когда я пишу time = Time('now'), он принимает строку 'now' и хочет поместить ее в часах.

Я знаю, что есть временные модули, которые могут это сделать, но это предназначено для обучения.

Мой код:

import random, time 

class Time: 

    def __init__(self, hours=0, minutes=0, seconds=0, time_now=''): 
#  if time_now == 'now': 
#   now() 
     time = abs(3600*hours + 60*minutes + seconds) 
     self.hour = time//3600 
     self.min = time//60%60 
     self.sec = time%60 

    def __repr__(self): 
     return '{}:{:02}:{:02}'.format(self.hour,self.min,self.sec) 

    def __add__(self, other): 
     if isinstance(other, Time): 
      return Time(self.hour+other.hour, self.min+other.min, self.sec+other.sec) 
     if isinstance(other, int): 
      return Time(self.hour, self.min, self.sec+other) 

    __radd__ = __add__ 

    def __sub__(self, other): 
     return Time(seconds = self.__int__() - other.__int__()) 

    def __mul__(self, other): 
     return Time(self.hour*other.hour, self.min*other.min, self.sec*other.sec) 

    def __int__(self): 
     return 3600*self.hour + 60*self.min + self.sec 

    def __eq__(self, other): 
     return self.__int__() == other.__int__() 

    def __lt__(self, other): 
     return self.__int__() < other.__int__() 

    #writing out hour/min/sec what we want 
    def __getitem__(self, key): 
     if key == 0: 
      return self.hour 
     if key == 1: 
      return self.min 
     if key == 2: 
      return self.sec 



#time now 

def now(): 
    a=(time.localtime()[3:6]) 
    return Time(a[0],a[1],a[2]) 
+1

[Хорошее видео] (https://www.youtube.com/watch?v=-5wpm-gesOY) на этом :) – wenzul

+0

Какой смысл это умножать раз? Класс выглядит много непоследовательным для меня и для обучения. Может быть, лучший пример для перезаписи методов \ _ \ _, чем время ... – wenzul

+0

@wenzul Посмотрите это видео позже, спасибо! О времени умножения, это глупо, но это то, что я должен был сделать: D – Matis

ответ

1

Python не имеет метод overloading, поэтому единственным вариантом является «играть» с аргументами:

Вы можете сделать что-то, что ИМХО очень плохо (понижен очень плохо к meeeeh ... так, так после прочтения @ivan-pozdeev «s комментарии в этом ответе)

class Time: 
    def __init__(self, hours=0, minutes=0, seconds=0, time_now=''): 
     if hours == 'now': 
      tmp_t = now() 
      self.hour = tmp_t.hour 
      self.min = tmp_t.min 
      self.sec = tmp_t.sec 
     else: 
      t = abs(3600*hours + 60*minutes + seconds) 
      self.hour = t//3600 
      self.min = t//60%60 
      self.sec = t%60 

... ну, что работает:

>>> a = Time('now') 
>>> print vars(a) 
{'sec': 20, 'hour': 15, 'min': 18} 
>>> 
>>> a = Time(hours=19, minutes=4, seconds=5) 
>>> print vars(a) 
{'sec': 5, 'hour': 19, 'min': 4} 

Но это оставляет код в очень странном состоянии. Очень трудно читать. Я, конечно, попытался бы прийти совсем другим путем ...

Я также изменил time переменную внутри __init__ к t, потому что в противоречие с time именем из import time

+0

Привет, спасибо за ваш ответ! К сожалению, я получаю сообщение об ошибке, вы использовали мою функцию сейчас() или вы ее отредактировали? 'AttributeError: объект 'Time' не имеет атрибута 'localtime'' – Matis

+0

I (kinda) использовал ваш: я начал свой ответ, используя' datetime'. Затем я понял о вашей функции 'now'. Я взял то, что сделал, и соответствующим образом адаптировал код. Нет редактирования. *: -) * – BorrajaX

+0

Кажется, что где-то в вашем коде вы создаете переменную 'time', которая перезаписывает модуль' time' («время», которое поступает из 'import time'). Вы делали что-то вроде 'time = Time (...)'? – BorrajaX

0

Почти никогда пытаться реализовать свой собственный модуль времени. Это трудоемкий и дефектный. Используйте time или datetime. Все ваши потребности уже реализованы каким-то образом.

+1

Я знаю, но это для учебных целей. – Matis

+0

Хорошо, это почти. Но я все равно дал ответ, потому что вы этого не писали. :) – wenzul

+0

Да, я сожалею об этом, я добавил его там. – Matis

1

Вы можете использовать вызов с именованными параметрами: Time(time_now='now'), но это выглядит слишком reiterative.
Если бы я использовал именованные параметры, я бы вместо этого изменил его на логическое и использовал что-то вроде Time(now=True), которое выглядит немного чище.

Но я думаю, что лучшая альтернатива, чтобы сделать ваши объекты «теперь» быть построены из вашей now() функции, которую я бы перейти на статический метод:

class Time(object): 
    #... 
    @classmethod 
    def now(cls): 
     a=(time.localtime()[3:6]) 
     return cls(a[0],a[1],a[2]) 

Таким образом, вы бы построить свой прямо сейчас объекты, такие как x = Time.now() вместо x = Time('now')

+0

отлично работает! Благодарю. Подождите, если кто-то может придумать другое решение ближе к тому, что я хотел, если нет, я отмечаю это как ответ. – Matis

1

Для обработки гибкий аргумент за то, что доступно со статическими аргументами, you may use *args and/or **kwargs:

def __init__(self, *args, **kwargs): 
    a_seq=('hours','minutes','seconds') 
    if len(args)>0 and args[0]=='now': 
     now_=now() 
     self.__dict__.update(a,getattr(now_,a) for a in a_seq) 
    else: 
     t=0 
     for i,a in enumerate(a_seq): 
      try: v=args[i] 
      except IndexError: v=kwargs.get(a,0) 
      else: if a in kwargs: raise TypeError("multiple values given for argument `%s'"%a) 
      t+=v 
      t*=60 
     for a in a_seq[-1:0:-1]: 
      setattr(self,a,t%60) 
      t//=60 
     setattr(self,a_seq[0],t) 

(I переименовали поля с тем же именем, что и аргументы, чтобы облегчить использование отражения. Отражение используется здесь для устранения дублирования кода (без него оно будет примерно в 1,5 раза дольше).)

В этом конкретном случае, однако, BorrajaX's solution намного проще, поскольку отклонение от обычного статического списка аргументов здесь незначительно (на самом деле, try-except-else во второй половине моего кода ничего не делает, кроме эмулирования).

+0

Да, с помощью '* args' и' ** kwargs' это то, что я сделал, чтобы не учитывать, что я сделал в своем ответе * Плохой код * Обычно я стараюсь не слишком сильно отклоняться от исходного кода OP (вот почему мой ответ выглядит так, как он есть), но этот способ позволяет лучше контролировать аргументы. – BorrajaX

Смежные вопросы