子类化日期时间:是否有更好的方法在算术运算后维护结果对象类型?
我最近遇到了一种情况,我需要子类化 datetime.datetime
和 datetime.timedelta
以便添加一些方法。不过,我立即发现,当我希望任何算术运算返回 mydatetime.mydatetime
实例时,它都会返回 datetime.datetime
对象。以下是一位同事帮助我解决这个问题的解决方案。有人有更简洁或更方便的建议吗?我在这里所做的事情有危险吗?我错过了什么重要的事情吗?
from datetime import datetime, timedelta
def _to_mydatetime(native):
'''Instantiates object of appropriate class based on class
of the input object.'''
if hasattr(native, 'timetuple'):
return mydatetime(*native.timetuple()[:6])
else:
return mytimedelta(native.days, native.seconds)
class mydatetime(datetime):
'''Subclass of datetime'''
def __add__(self, other):
result = super(mydatetime, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mydatetime, self).__sub__(other)
return _to_mydatetime(result)
class mytimedelta(timedelta):
def __add__(self, other):
result = super(mytimedelta, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mytimedelta, self).__sub__(other)
return _to_mydatetime(result)
def __div__(self, other):
result = super(mytimedelta, self).__div__(other)
return _to_mydatetime(result)
def __rmul__(self, other):
result = super(mytimedelta, self).__rmul__(other)
return _to_mydatetime(result)
def __mul__(self, other):
result = super(mytimedelta, self).__mul__(other)
return _to_mydatetime(result)
I recently ran into a situatiton where I needed to subclass datetime.datetime
and datetime.timedelta
in order to add a few methods. I immediately found, though, that any arithmetic operations would return a datetime.datetime
object when I expected it to return a mydatetime.mydatetime
instance instead. Below is the solution that a co-worker helped me out with for this problem. Does anyone have a more concise or convenient suggestion? Are there any dangers to what I have done here? Am I missing anything important?
from datetime import datetime, timedelta
def _to_mydatetime(native):
'''Instantiates object of appropriate class based on class
of the input object.'''
if hasattr(native, 'timetuple'):
return mydatetime(*native.timetuple()[:6])
else:
return mytimedelta(native.days, native.seconds)
class mydatetime(datetime):
'''Subclass of datetime'''
def __add__(self, other):
result = super(mydatetime, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mydatetime, self).__sub__(other)
return _to_mydatetime(result)
class mytimedelta(timedelta):
def __add__(self, other):
result = super(mytimedelta, self).__add__(other)
return _to_mydatetime(result)
def __sub__(self, other):
result = super(mytimedelta, self).__sub__(other)
return _to_mydatetime(result)
def __div__(self, other):
result = super(mytimedelta, self).__div__(other)
return _to_mydatetime(result)
def __rmul__(self, other):
result = super(mytimedelta, self).__rmul__(other)
return _to_mydatetime(result)
def __mul__(self, other):
result = super(mytimedelta, self).__mul__(other)
return _to_mydatetime(result)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,这是正确的方法(我只是将转换器方法分成两个)。不过,Python 允许您减少代码重复:
convproxy
下的神秘代码只是在创建类时生成指定方法的一种聪明方法,每个方法都调用一个超类方法并从中创建一个子类使用指定转换器函数的结果。Well, this is the right way to do it (i'd just split the converter method into two). Python allows you to reduce code duplication though:
The cryptic code under
convproxy
is just a smart-aleck way to generate the specified methods when creating a class, each of which calls a superclass method and creates a subclass from the result using the specified converter function.