【发布时间】:2020-05-11 15:53:30
【问题描述】:
我正在尝试扩展 Python datetime.timedelta 以用于越野比赛结果。我想从格式为u"mm:ss.s" 的字符串构造一个对象。我可以使用工厂设计模式和@classmethod 注释来实现这一点。我将如何通过覆盖__init__ 和/或__new__ 来完成同样的任务?
使用下面的代码,构造对象会引发 TypeError。注意__init__ 没有被调用,因为'in my __init__' 没有被打印出来。
import datetime
import re
class RaceTimedelta(datetime.timedelta):
def __init__(self, timestr = ''):
print 'in my __init__'
m = re.match(r'(\d+):(\d+\.\d+)', timestr)
if m:
mins = int(m.group(1))
secs = float(m.group(2))
super(RaceTimedelta, self).__init__(minutes = mins, seconds = secs)
else:
raise ValueError('timestr not in format u"mm:ss.d"')
这是错误:
>>> from mytimedelta import RaceTimedelta
>>> RaceTimedelta(u'24:45.7')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported type for timedelta days component: unicode
>>>
如果我将代码从 __init__ 移动到 __new__,我会得到以下信息。注意这一次,输出显示我的__new__函数被调用了。
>>> RaceTimedelta(u'24:45.7')
in my __new__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mytimedelta.py", line 16, in __new__
super(RaceTimedelta, self).__new__(minutes = mins, seconds = secs)
TypeError: datetime.timedelta.__new__(): not enough arguments
>>>
【问题讨论】:
-
datetime是用C实现的。如果你只想替换构造函数,只要有一个方便的函数来解析字符串会容易得多。 -
感谢您的建议。最终目标是在比赛结果表中显示时间。出于这个原因,我还想覆盖
__str__,以便更轻松地使用漂亮的打印机模块。