web-dev-qa-db-ja.com

Pythonのクラスのインスタンスで数を割る

Timeというクラスがあり、Frequencyクラスを実装する必要があります。 intのインスタンスを取得するために、floatsまたはTimesをFrequencyのインスタンスで除算する方法を教えてください。

私はすでに__div____truediv____floordiv__およびその他のPython特別なメソッドについて知っています。また、コードでそれらを使用して、クラスのインスタンスを他のクラスの数値またはインスタンスですが、数値を自分のクラスのインスタンスで除算する方法が見つかりません。

Pythonでクラスのインスタンスで数値を除算することを実装することは可能ですか?

24
Lucidiot

___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_
28
Right leg

はい。浮動小数点数または整数を受け取ったときに、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 docsには、カスタムクラスの 算術演算の実装 の完全な例が含まれています。

互換性のない型を処理する適切な方法は、特別な値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'
_
9
Håken Lid

__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)

これらのメソッドは、2項算術演算(+、-、*、@、/、//、%、divmod()、pow()、**、<<、>>、&、^、|)を実装するために呼び出されます。反映(スワップ)されたオペランド。これらの関数は、左のオペランドが対応する演算[3]をサポートせず、オペランドのタイプが異なる場合にのみ呼び出されます。 [4]たとえば、式x-yを評価するには、yが__rsub__()メソッドを持つクラスのインスタンスであり、y.__rsub__(x)がNotImplementedを返した場合にx.__sub__(y)が呼び出されます。

3