Is it possible to be a virtual subclass of a built-in type?

Is it possible to make a user-defined type a virtual subclass of a built-in type in python? I would like my class to be considered a subclass int

, however I didn't want to inherit directly like this:

class MyInt(int):
    '''Do some stuff kind of like an int, but not exactly'''
    pass

      

Since then, my class has become virtually unchanged whether I want it or not. For example, it becomes impossible to use methods such as __iadd__

and __isub__

, since it int

does not have the ability to modify itself. I could inherit from numbers.Integral

, but then when someone calls isinstance(myIntObj, int)

or issubclass(MyInt, int)

, the answer is False

. I understand that classes with metaclass ABCMeta can use a method register

to register classes as virtual base classes that are not actually inherited from them. Is there a way to do this with built-in types? Something like:

registerAsParent(int, MyInt)

      

I've looked around (both in python documentation and in general on the internet) and haven't found anything close to what I'm looking for yet. Is this what I'm asking just completely impossible?

+3


source to share


1 answer


Not sure what exactly you are trying to do as what you are asking is not possible as primitive types are essentially immutable. However, you can override __iadd__

etc. to return the result with the type you want. Note that I have changed the signs (used -

instead of +

) for the drama.

>>> class MyInt(int):
...     def __iadd__(self, other):
...         return MyInt(self - other)
...     def __add__(self, other):
...         return MyInt(self - other)
... 
>>> i = MyInt(4)
>>> i += 1
>>> type(i)
<class '__main__.MyInt'>
>>> i
3
>>> i + 5
-2
>>> type(i + 5)
<class '__main__.MyInt'>

      

Flush and repeat whatever other magic methods you would need to do in order to have a "correct" int subclass (even if "virtual" users might expect them to work in a certain way).

Oh yeah, for extensibility (as if it weren't crazy already) instead self.__class__

use self.__class__

for results



class MyInt(int):
    def __iadd__(self, other):
        return self.__class__(self - other)

      

So if we have another subclass of this.

>>> class MyOtherInt(MyInt):
...     def __iadd__(self, other):
...         return self.__class__(self + other)
... 
>>> i = MyOtherInt(4)
>>> i += 4
>>> i
8
>>> type(i)
<class '__main__.MyOtherInt'>

      

+1


source







All Articles