views:

280

answers:

3

In Python, I'm trying to extend the builtin 'int' type. In doing so I want to pass in some keywoard arguments to the constructor, so I do this:

class C(int):
     def __init__(self, val, **kwargs):
         super(C, self).__init__(val)
         # Do something with kwargs here...

However while calling C(3) works fine, C(3, a=4) gives:

'a' is an invalid keyword argument for this function`

and C.__mro__ returns the expected:

(<class '__main__.C'>, <type 'int'>, <type 'object'>)

But it seems that Python is trying to call int.__init__ first... Anyone know why? Is this a bug in the interpreter?

+2  A: 

You should be overriding "__new__", not "__init__" as ints are immutable.

David Raznick
+2  A: 

The docs for the Python data model advise using __new__:

object.new(cls[, ...])

new() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

Something like this should do it for the example you gave:

class C(int):

    def __new__(cls, val, **kwargs):
        inst = super(C, cls).__new__(cls, val)
        inst.a = kwargs.get('a', 0)
        return inst
Jarret Hardie
+2  A: 

What everyone else (so far) said. Int are immutable, so you have to use new.

Also see (the accepted answers to):

scrible