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?
source to share
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'>
source to share