接受单个字符串而不是普通参数

时间:2014-12-02 20:07:47

标签: python class time

大家好,我有一个与时间一致的课程,例如你输入两次,你可以加总它们(现在它并不重要,它超过23:59:59)或乘以它们等。默认输入为零。还有一个返回当前时间的函数。我可以致电time = Time(),返回0:00:00time = 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])

4 个答案:

答案 0 :(得分:1)

您可以使用带有命名参数的调用:Time(time_now='now'),但这看起来过于重复。
如果我使用的是命名参数,我会将其更改为布尔值并使用类似Time(now=True)的内容,它看起来更清晰。

但我认为更好的选择是让你的#34;现在&#34;对象可以从now()函数构建,我将移动到静态方法:

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

因此,您构建了 now 对象,例如x = Time.now()而不是x = Time('now')

答案 1 :(得分:1)

Python没有方法overloading,所以你唯一的选择是&#34;播放&#34;参数:

你可以做一些恕我直言非常糟糕的事情(将非常糟糕降级为 meeeeh ...所以,所以阅读@ ivan-pozdeev&#39;在这个答案的评论)

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名称相冲突

答案 2 :(得分: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)

(我将这些字段重命名为与参数相同的名称,以便更容易使用反射。这里使用反射来消除代码重复(没有它,它的长度大约是后者的1.5倍)。)

在这种特殊情况下,BorrajaX's solution要简单得多,因为这里与普通静态参数列表的偏差很小(实际上,我代码的后半部分的try-except-else什么都不做但是效仿它。)

答案 3 :(得分:0)

几乎从不尝试实现自己的时间模块。这是耗时且有缺陷的。使用timedatetime。您的所有需求都已经以某种方式实现。