1

I was trying to answer this question here with an inherited class solution, but when I tested it on my IDE my solution didn't came out as I expected. I did some search but couldn't find an answer.

Here was my proposed solution:

class PseudoInteger(int):
    def __init__(self, x, base=10, hid_obj=""):
        self.hidden_object = hid_obj
        super(int, PseudoInteger).__init__(x, base)


pseudo_integer = PseudoInteger('5', hid_obj="Hello World")
print(5 + pseudo_integer) # Expects "10"
print(pseudo_integer == 5) # Expects "True"
print(pseudo_integer.hidden_object) # Expects "Hello World!"

To my understanding this should work in theory. But when I run it this is what I get:

    pseudo_integer = PseudoInteger('5', hid_obj="Hello World")
TypeError: 'hid_obj' is an invalid keyword argument for this function

I've tried adding base=10 when initiating the instance but it still fails:

    pseudo_integer = PseudoInteger('5', base=10, hid_obj="Hello World")
TypeError: int() takes at most 2 arguments (3 given)

I thought I had messed something up so I write my own class and inherit it, but it works fine:

class foo(object):
    def __init__(self, x, y=10):
        pass

class bar(foo):
    def __init__(self, x, y=10, z=""):
        self.z = z
        super(foo, bar).__init__(x, y)

foobar = bar(1, z="hello")
print(foobar.z)

# Output
# hello

My question is - why couldn't I inherit the built-in int class and add an additional argument, but it works fine when it's inherited from my foo class? Is it a limitation or did I mess up?


In addition to @Melvin's suggestion of super() not needing args in Python 3, I tried it on my custom class, it works. But in the built-in inherited class I got another unexpected behaviour:

    super().__init__(x, base)
TypeError: object.__init__() takes no parameters

Built-ins are weird man.

r.ook
  • 13,466
  • 2
  • 22
  • 39
  • 1
    Is this python 2 or 3? If it's 3 you don't need arg in your super(). – Melvin Jan 26 '18 at 16:49
  • @Melvin I'm running on Python 3.6.3. I can do `super()` without arg in my custom class *but not* in the inherited `int` class. I get another unexpected behaviour: `TypeError: object.__init__() takes no parameters`. This is... another question? – r.ook Jan 26 '18 at 16:52
  • Well `TypeError: object.__init__() takes no parameters` just means that `int` does not take in any input arguments in its `__init__`, I've not actually inherited from `int` before, give me some time to try it out :) – Melvin Jan 26 '18 at 16:58
  • 2
    The parameters you're passing to `__init__` are first passed to `__new__` and since your subclass does not override the `__new__` of the parent class, signatures mismatch. Here's a small working example: https://repl.it/repls/ClearCourageousAlbertosaurus – Moses Koledoye Jan 26 '18 at 16:58
  • @Mevin That's not the issue. They can add custom parameters to their subclass. – Moses Koledoye Jan 26 '18 at 16:58
  • Appreciate all the comments and answers here. It just goes to show my google-fu is not as strong as I thought. – r.ook Jan 26 '18 at 16:58
  • @MosesKoledoye woops sorry – Melvin Jan 26 '18 at 16:59
  • @MosesKoledoye that's beautiful. I looked into the dupe threads and still couldn't understand the `__new__()` usage, but your sample made it click. Much appreciated! Would have happily accepted it as an answer but the question was closed. – r.ook Jan 26 '18 at 17:05

1 Answers1

0

int is immutable so you can't modify it after it is created, use __new__ instead. Try this:

class PseudoInteger(int):
    def __new__(self, x, base=10, hid_obj=""):
        self.hidden_object = hid_obj
        super(int, PseudoInteger).__new__(x, base)

Possible Duplicate of: Subclassing int in Python

kmfsousa
  • 183
  • 1
  • 1
  • 11