Does __init__ of subclass need the same argument types as __init__of base class?

S

Sibylle Koczian

I do more or less understand this error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required

I don't understand at all why I get the same message with this little
script:

############################
import datetime

class meindatum(datetime.date):
def __init__(self, datum):
print "meindatum"
datetime.date.__init__(self, datum.year, datum.month, datum.day)
# Using super() doesn't make a difference:
# super(meindatum, self).__init__(self, datum.year, datum.month,
# datum.day)

x1 = datetime.date.today()
print repr(x1)
x2 = meindatum(x1)
print repr(x2)
#######################################

Executing this from the command line:

sib@Elend:~> python /windows/E/LinWin/Python/datum_ableiten.py
datetime.date(2009, 3, 25)
Traceback (most recent call last):
File "/windows/E/LinWin/Python/datum_ableiten.py", line 12, in <module>
x2 = meindatum(x1)
TypeError: an integer is required
sib@Elend:~>

The print command inside the __init__ method isn't executed, so that
method doesn't seem to start at all. Looks to me as if
meindatum.__init__() needs the same arguments as
datetime.date.__init__() does, but I can't really believe that (Python
isn't Pascal).

Using Python 2.6.1, tried this on Linux and Windows XP.

Thank you for explanations,
Sibylle
 
B

Bruno Desthuilliers

Sibylle Koczian a écrit :
(snip)
I don't understand at all why I get the same message with this little
script:

############################
import datetime

class meindatum(datetime.date):
def __init__(self, datum):
print "meindatum"
datetime.date.__init__(self, datum.year, datum.month, datum.day)

x1 = datetime.date.today()
print repr(x1)
x2 = meindatum(x1)
print repr(x2)
#######################################

Executing this from the command line:

sib@Elend:~> python /windows/E/LinWin/Python/datum_ableiten.py
datetime.date(2009, 3, 25)
Traceback (most recent call last):
File "/windows/E/LinWin/Python/datum_ableiten.py", line 12, in <module>
x2 = meindatum(x1)
TypeError: an integer is required
sib@Elend:~>

The print command inside the __init__ method isn't executed, so that
method doesn't seem to start at all.

this often happens with (usually C-coded) immutable types. The
initializer is not called, only the "proper" constructor (__new__). The
following should work (not tested):

class Meindatum(datetime.date):
def __new__(self, datum):
print "meindatum"
return datetime.date(datum.year, datum.month, datum.day)


HTH
 
H

Hrvoje Niksic

this often happens with (usually C-coded) immutable types. The
initializer is not called, only the "proper" constructor (__new__).

More specifically, __init__ is called, but only after __new__ has
finished, and __new__ gets the arguments passed in the constructor
expression. Since __new__ raises an exception for those arguments,
__init__ is never reached.

The fix is in such cases is, as you point out, to override __new__ and
not bother with __init__ at all.
 
S

Sibylle Koczian

Bruno said:
Sibylle Koczian a écrit :
(snip)

this often happens with (usually C-coded) immutable types. The
initializer is not called, only the "proper" constructor (__new__). The
following should work (not tested):

class Meindatum(datetime.date):
def __new__(self, datum):
print "meindatum"
return datetime.date(datum.year, datum.month, datum.day)

Thank you, that works, and I learned something (didn't know how Python
objects are created). After some trial, error and searching on the
Python website I found how to give Meindatum additional data attributes.
Now it looks like this:

class Sonderdatum(datetime.date):
"""
Date with additional attribute (integer)
"""
def __new__(cls, datum):
print "Hier Sonderdatum.__new__"
(x, y, z) = (datum.year, datum.month, datum.day)
print "Jahr: %d, Monat: %d, Tag: %d" % (x, y, z)
return super(Sonderdatum, cls).__new__(cls, datum.year,
datum.month,
datum.day)

def __init__(self, datum, sonder=0):
print "Hier Sonderdatum.__init__"
# superclass __init__ is _not_ called!
# super(Sonderdatum, self).__init__(x, y, z)
self.sonder = sonder

def testeSondertage():
datum = datetime.datetime.strptime("01.01.2009", "%x")
print repr(datum.date())
xx = Sonderdatum(datum.date())
print xx.year, xx.month, xx.day, xx.sonder

if __name__ == "__main__":
locale.setlocale(locale.LC_ALL, '')
testeSondertage()

And now I'll put this into something remotely useful.

Je vous prie d'agréer mes meilleurs salutations,
Sibylle
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top