Подтвердить что ты не робот

Разделение числа экземплярами моего класса в Python

У меня есть класс под названием Time, и мне нужно реализовать класс Frequency. Как я могу реализовать разделение int или float экземпляром Time, чтобы получить экземпляр Frequency?

Я уже знаю о __div__, __truediv__, __floordiv__ и других специальных методах Python, и я уже использую их в своем коде, чтобы разделить экземпляры классов на числа или экземпляры других классов, но я не могу найти способ разделить число экземпляром моего класса.

Можно ли реализовать деление числа на экземпляр класса в Python?

4b9b3361

Ответ 1

Метод __rtruediv__ - это то, что вы ищете. Когда x / y выполняется, если type(x) не реализует метод __div__(self, other), где other может быть класса type(y), тогда выполняется type(y).__rtruediv__(y, x), и его результат возвращается.

Использование:

class Foo:
    def __init__(self, x):
        self.x = x

    def __truediv__(self, other):
        return self.x / other

    def __rtruediv__(self, other):
        return other / self.x
>>> f = Foo(10)    
>>> f / 10
1.0
>>> 10 / f
1.0

Ответ 2

Да. Вам просто нужно убедиться, что Time.__rtruediv__() возвращает экземпляр Frequency, когда он получает поплавок или целое число.

Использование:

>>> 100 / Time(2)
Frequency(50.0)
>>> 2.5 / Time(5)
Frequency(0.5)

Реализация:

class Time:
  def __init__(self, value):
    self.value = value

  def __rtruediv__(self, other):
    if not isinstance(other, (int, float)):
      return NotImplemented
    return Frequency(other / self.value)

class Frequency:
  def __init__(self, value):
    self.value = value

  def __repr__(self):
    return '{}({})'.format(self.__class__.__name__, self.value)

Документы python содержат полный пример реализации арифметических операций для ваших пользовательских классов.

Правильный способ обработки несовместимых типов - вернуть специальное значение NotImplemented.

NotImplemented

Специальное значение, которое должно быть возвращено двоичным специальные методы (например, __eq__(), __lt__(), __add__(), __rsub__() и т.д.) чтобы указать, что операция не выполняется в отношении другой тип

Предположим, вы пытаетесь использовать неподдерживаемый комплексный номер, возврат NotImplemented в конечном итоге приведет к TypeError с правильным сообщением об ошибке. (по крайней мере, на python 3)

>>> 100j / Time(2)

Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'complex' and 'Time'

Ответ 3

вам нужно реализовать __rtruediv__ и __rfloordiv__.

из документация

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

Эти методы вызывают для реализации двоичных арифметических операций (+, -, *, @,/,//,%, divmod(), pow(), **, <, → , &, ^, |) с отраженные (замененные) операнды. Эти функции вызываются только в том случае, если левый операнд не поддерживает соответствующую операцию [3], а операнды имеют разные типы. [4] Например, чтобы оценить выражение x - y, где y - экземпляр класса, который имеет __rsub__(), y.__rsub__(x) вызывается, если x.__sub__(y) возвращает NotImplemented.