Возможно ли быть виртуальным подклассом встроенного типа?

Можно ли сделать определяемый пользователем тип виртуальным подклассом встроенного типа в python? Я хотел бы, чтобы мой класс считался подклассом int, однако я не хотел наследовать прямо так:

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

С тех пор мой класс становится фактически неизменным, хочу ли я этого или нет. Например, становится невозможным использовать такие методы, как __iadd__ и __isub__, поскольку int не имеет возможности модифицировать себя. Я мог бы наследовать от numbers.Integral, но тогда, когда кто-то называет isinstance(********, int) или issubclass(*****, int), ответ будет False. Я понимаю, что классы с метаклассом ABCMeta могут использовать метод register для регистрации классов как виртуальных базовых классов, которые на самом деле не унаследованы от них. Есть ли способ сделать это со встроенными типами? Что-то вроде:

registerAsParent(int, *****)

Я огляделся (как в документации на python, так и в целом в Интернете) и еще не нашел ничего близкого к тому, что я ищу. Это то, что я прошу просто совершенно невозможно?

1 ответ

Не уверен, что именно вы пытаетесь сделать, поскольку то, что вы просите, невозможно, поскольку примитивные типы по существу неизменяемы. Однако вы можете переопределить __iadd__ и т.д., Чтобы вернуть результат с нужным типом. Обратите внимание, что я изменил знаки (используется - вместо +) для драмы.

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

Промойте и повторите все остальные магические методы, которые вам нужно было бы сделать, чтобы иметь "правильный" подкласс int (даже если "виртуальные" пользователи могут ожидать, что они будут работать определенным образом).

О, да, для расширяемости (как будто это уже не было безумием) вместо self.__class__ используйте self.__class__ для результатов

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

Итак, если у нас есть другой подкласс этого.

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

licensed under cc by-sa 3.0 with attribution.