[Tutor] modify values for object derived from datetime.datetime
Steven D'Aprano
steve at pearwood.info
Fri Dec 16 11:26:23 CET 2011
rail shafigulin wrote:
> i writing some code to do device testing at my work. testing is related to
> date and time, so naturally i decided to create a class that inherits from
> datetime.datetime. main reason is that i need to add, subtract and compare
> datetime objects and datetime.datetime allows me to do that. here is the
> code:
>
> class LTime(datetime.datetime):
> TOLERANCE = 10
>
> def __new__(self, year, month, day, *args):
> if year == 0:
> year = 2000
> return super().__new__(self, year, month, day, *args)
By convention, the first argument of __new__ is normally spelled as "cls",
short for class, because the instance hasn't been created yet.
> def modify(self):
> self = self.replace(2012, 12, 12)
> print(self)
The replace method creates a new datetime object. Just because you assign it
to the name "self" doesn't mean you can change the existing datetime object.
That is simply impossible: datetime objects are immutable, like ints.
You might not quite understand why modifying immutable objects would be bad
(which is why Python doesn't allow it). I can simulate the effect with this
simple wrapper class:
>>> class Mutable:
... def __init__(self, value):
... self.value = value
... def __str__(self):
... return str(self.value)
... __repr__ = __str__
... def add(self, value):
... self.value += value
...
>>> one = Mutable(1) # Pretend this is the int 1
>>> print(one)
1
>>> x = one
>>> x.set(1) # pretend this was x += 1
>>> one # the int 1 has been modified in place
2
So if ints (and datetime objects) could be changed in place, you could never
be sure what value a literal like 1 would have.
Obviously this is useful in some situations, which is why we have mutable
objects like lists. But datetime objects are not mutable, a design choice made
by the creator of the module, so you cannot change it.
So you have to change your design. Instead of writing code like this:
today = LTime(2011, 12, 16)
# ...
# ... do stuff with today
# ...
today.modify(day=17) # fast forward in time to tomorrow
# ...
# ... do stuff with today, which is actually tomorrow
# ...
you need to change your code to be more like this:
today = LTime(2011, 12, 16)
# ...
# ... do stuff with today
# ...
tomorrow = today.modify(day=17)
# ...
# ... do stuff with tomorrow
# ...
--
Steven
More information about the Tutor
mailing list