问题
Is it possible to make a user defined type be a virtual subclass of a built in type in python? I would like my class to be considered a subclass of int
, however I don'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 becomes effectively immutable, whether I want it to be or not. For instance, it becomes impossible to use methods like __iadd__
and __isub__
since int
has no way to modify itself. I could inherit from numbers.Integral
, but then when someone calls isinstance(myIntObj, int)
or issubclass(MyInt, int)
the answer will be False
. I understand that classes with a metaclass of ABCMeta can use the method register
to register classes as virtual baseclasses that don't truly inherit from them. Is there some way to do this with built in types? Something like:
registerAsParent(int, MyInt)
I have looked around (both in the python documentation and generally online) and haven't yet found anything close to what I am looking for. Is what I am asking for just completely impossible?
回答1:
Not sure what exactly what you are trying to do, as what you are asking is impossible as primitive types are essentially immutable. However you can override __iadd__
and such to return the result with the type you want. Note that I reversed the signs (used -
instead of +
) for 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'>
Rinse and repeat for the rest of the magic methods, which you would have need to done anyway to have a "proper" subclass of int (even if "virtual" users might expect them to function a certain way).
Oh, yeah, for extensibility (as if this wasn't insane already) use self.__class__
instead for the results
class MyInt(int):
def __iadd__(self, other):
return self.__class__(self - other)
So if we have another subclass of that.
>>> class MyOtherInt(MyInt):
... def __iadd__(self, other):
... return self.__class__(self + other)
...
>>> i = MyOtherInt(4)
>>> i += 4
>>> i
8
>>> type(i)
<class '__main__.MyOtherInt'>
来源:https://stackoverflow.com/questions/25149315/is-it-possible-to-be-a-virtual-subclass-of-a-built-in-type