3

I need a class extending datetime.date adding logic that is relevant to my application. It used to work well with Python 2, but I don't understand how to write the constructor in Python 3. I thought the standard way to write a derived constructor in Python 3 was like this:

from datetime import date

class my_date(date):
    def __init__(self, year, month, day):
        super().__init__(year, month, day)

date(2020, 4, 18)
my_date(2020, 4, 18)

However, this code fails with:

Traceback (most recent call last):
  File "/tmp/test.py", line 8, in <module>
    my_date(2020, 4, 18)
  File "/tmp/test.py", line 5, in __init__
    super().__init__(year, month, day)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)

What should I do to properly call the super constructor?

In particular, datetime.date clearly accepts to be initialized with three numbers. Why does the error message say it takes one argument? And why is the problem in object.__init__() instead of in datetime.date.__init__()?

Giovanni Mascellani
  • 1,218
  • 2
  • 11
  • 26
  • 2
    Looking at the Python source of [`datetime.date`](https://github.com/python/cpython/blob/c606624af8d4cb3b4a052fb263bb983b3f87585b/Lib/datetime.py#L793) you’ll notice that it doesn’t have an `__init__()` method, only a `__new__()` constructor. That would explain the above error. Also note that `year`, `month`, `day` are decorated (i.e. read only) properties, not instance values. – Jens Apr 18 '20 at 08:01
  • 2
    Replace `super().__init__(year, month, day)` with `pass`. – accdias Apr 18 '20 at 08:01
  • 1
    That `__init__` was pointless even in Python 2. – user2357112 Apr 18 '20 at 08:15

2 Answers2

3

Answer from the comments:

Jens

Looking at the Python source of datetime.date you’ll notice that it doesn’t have an __init__() method, only a __new__() constructor. That would explain the above error. Also note that year, month, day are decorated (i.e. read only) properties, not instance values.

accdias

Replace super().__init__(year, month, day) with pass

from datetime import date

class my_date(date):
        pass

d1 = date(2020, 4, 18)
d2 = my_date(2020, 4, 18)

print(d1,d2) 

Outputs:

2020-04-18 2020-04-18

You might think about using composition instead of inheritance for whatever you need done:

class MyDateClass:
    def __init__(self, a_date):
        self.my_date = a_date

    # add members/methods that do stuff wiht a_date

instead of inheriting date.

See

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
-1

If you want to extend date then you can do something like this.

from datetime import date


class MyDate(date):
    def __init__(self, year, month, day):
       print(self)


print(date(2020, 4, 18))
print(MyDate(2020, 4, 20))