Subclassing standard class: how to write my own __init__?

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Fri Dec 19 08:59:40 EST 2008


kpalamartchouk at gmail.com a écrit :
> Dear All,
> 
> I am trying to create a class that would extend functionality of
> datetime.date by implementing some functions I need, for example an
> optional initialisation by (year, day_of_year) instead of (year,
> month, day).

If that's all you want, then you don't need a subclass - just a plain 
function returning a correctly constructed date object.

> I would like the class constructor to behave in the
> datetime's default way if there are no keyword arguments and do my own
> stuff if there are some.
> 
> Here is the minimal example:
> 
> =========================================
> from datetime import date, timedelta
> 
> class MyDateTime(date):

Naming it MyDateTime when it's a date is a bit misleading

>     def __init__(self, *arg, **kw):
>         if len(kw):

           if kw: # empty dict eval to False

>             year = kw['year']
>             doy = kw['doy']

Will raise a KeyError. Either don't use **kw, or catch the KeyError and 
raise a TypeError instead (which is what's expected when calling a 
function with wrong arguments)

>             my_date = date(year=year, month=1, day=1) + timedelta
> (days=doy-1)
>             date.__init__(self, year = my_date.year, month =
> my_date.month, day = my_date.day)
>         else:
>             date.__init__(self, *arg)
> 
> date1 = MyDateTime(2008, 12, 19)
> date2 = MyDateTime(year=2008, doy=354)
> =========================================
> 
> It works fine when I don't supply any keyword arguments. But if I do,
> TypeError is happening:
> 
> TypeError: function takes exactly 3 arguments (1 given)
 >
> Could you help me to understand where I am wrong?

Some classes implements the __new__ method too (the 'proper' 
constructor), and date is one of them.

class MyDate(date):
     def __new__(cls, year, month=None, day=None, doy=None):
         if doy:
             assert month is None and day is None
             d = date(year,1, 1) + timedelta(days=doy-1)
             month = d.month
             day = d.day
         return date.__new__(cls, year, month, day)

date1 = MyDate(2008, 12, 19)
date2 = MyDate(2008, doy=365)

HTH



More information about the Python-list mailing list