Я пытаюсь расширить Python datetime.datetime
класс с несколькими дополнительными методами. Так, например, я делаю:
import datetime
class DateTime(datetime.datetime):
def millisecond(self):
return self.microsecond/1000
но затем если я делаю
>>> d = DateTime(2010, 07, 11, microsecond=3000)
>>> print d.millisecond()
3
>>> delta = datetime.timedelta(hours=4)
>>> newd = d + delta
>>> print newd.millisecond()
AttributeError: 'datetime.datetime' object has no attribute 'millisecond'
Это, очевидно, потому что выполнение d + delta
вызовы datetime.datetime.__add__()
метод, который возвращает a datetime.datetime
объект.
Есть ли любой способ, которым я могу сделать это datetime.datetime
объектное преобразование в a DateTime
объект? Или я должен был бы повторно реализовать все операторы в моем DateTime
разделить на подклассы для возврата корректного типа?
В данном случае я бы предпочел простые автономные функции:
import datetime
def millisecond(dt):
return dt.microsecond/1000
Примеси возможны в Python (см. Комментарий), но я думаю, что в таких случаях они излишни.
На простом уровне вы можете сделать что-то вроде этого
import datetime
def millisecond(self):
return self.microsecond/1000
datetime.datetime.millisecond = millisecond
Однако динамически вставленный миксин может быть более аккуратным - или просто определение функции и передача ей экземпляра datetime.
В целом monkeypatching не очень похож на Pythonic - это больше похоже на Ruby-подход к проблемам.
Я попытался реализовать решение с использованием обезьяньего патча, но обнаружил ошибку:
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
Это происходит с datetime.datetime.millisecond = миллисекунда
и GvR's __ metaclass __ = monkeypatch_class
.
Возможно, datetime.so
не может быть исправлен как обезьяна. Если это правда, то вы можете подумать над этим:
import datetime
class DateTime(datetime.datetime):
@property
def millisecond(self):
return self.microsecond/1000.0
def __add__(self,other):
result=super(DateTime,self).__add__(other)
result=DateTime(result.year,
result.month,
result.day,
result.hour,
result.minute,
result.second,
result.microsecond,
result.tzinfo)
return result
__radd__=__add__
d = DateTime(2010, 07, 11, microsecond=3000)
print d.millisecond
# 3.0
delta = datetime.timedelta(hours=4)
newd = d + delta
print newd.millisecond
# 3.0
# This uses __radd__
newd = delta + d
print newd.millisecond
# 3.0