Python データ型 を 定義 するとき の 特殊メソット (__add__)など

皆さんはPythonを便利にするために型を自分で定義したことはありますか？
そこでデータ型を定義するとき最も大切なのは***特殊メゾット***というものです。
特殊メソットはアンダーバー4個の間に英語を入力して定義できます。

特殊メソットの役割は簡単に言うと
***「データ型を関数で使った時のふるまいを定義する関数」***
です。

図で説明すると、

![説明1](https://lh3.googleusercontent.com/w5pspEIbC1GHAuADcRNR1fAnvA46UAMwmia1r-yquK-qxfHsoeg708gTGrqS5qjSYkK4gW-NxJ8ugO81sNVzCkIbXU8kai3fVLt5S3dkNq7sdo-JRqkEgYB5NVD2qn1HD8_eDX694tYZ_2YT18pshdogIiAbiQr5MPn1-MpXxA-oE8UNTl-ZM4jUIQGAcGZOs4rzcUFlBsj0pu9DwAPu3qd1h9nLaQzS9jCJ8Gio0-blSrBqc88Is9ZtMat8pXJtunS-3aSUhEaCwr8WQnXNlGLyaZHSHXorBQEqUUSQSzyX_GTviPPaK8ID_vXEV2m5tWS17JBGRtFpc_SX2yX9_daL4b5dwrYnM7yz0MU2-NXpValWNGnzDxOWg7c6F0QfhFLebjwq2Ka-rdJGzhvzSDZr1DjbR_Y6SBlPD3jJuzWatiNTtsvbfR7RUy7EJhuulpI4Dz05zIaERDIvNP5URXuPu9x263cOs35h5gajgss_LAXtm-FOlcIalJRdasoSYiua07y4n5KhGcXWTH2KPWcvLzNcPGQnBcYkrrFq9NHuCcoFYNLFfSkbBw7MHDefTKmpoHGpc8cqkI4P_zJjMiSZudvPT9ov31JdS0b4Cn81fYuzpAx4MOH6Zo_20qUsSnY21yvWfae4dXlkif3VYLgTVaRSpm8Aa17Ph3ZGMAJnEY171znNh-1UsKNXD9TWLpi3WK0YZIsuFEXgQczxnPVgdO2JaRj8i80Tqj5YX-gvbob_epYmp-iAt3Q3XQ=w951-h495-no?authuser=0)
といった感じです。

主に下のような特殊メゾットがあります。
|特殊メソット                            |機能                                                  |
|:--------------------------------------|:----------------------------------------------------:|
|```__add__(self, other)```             |<br>```self + other```の計算のふるまいを定義<br>&thinsp;|
|```__pos__(self)```                    |<br>```+self```の計算のふるまいを定義<br>&thinsp;|
|```__sub__(self, other)```             |<br>```self - other```の計算のふるまいを定義<br>&thinsp;|
|```__neg__(self)```                    |<br>```-self```の計算のふるまいを定義<br>&thinsp;|
|```__pow__(self, other)```             |<br>```self ** other```の計算のふるまいを定義<br>&thinsp;|
|```__truediv__(self, other)```         |<br>```self / other```の計算のふるまいを定義<br>&thinsp;|
|```__floordiv__(self, other)```        |<br>```self // other```の計算のふるまいを定義<br>&thinsp;|
|```__divmod__(self, other)```          |<br>```self % other```の計算のふるまいを定義<br>&thinsp;|
|```__round__(self, other)```           |<br>```round(self, other)```の計算のふるまいを定義<br>&thinsp;|
|```__eq__(self, other)```              |<br>```self == other```のふるまいを定義<br>&thinsp;|
|```__ne__(self, other)```              |<br>```self != other```のふるまいを定義<br>&thinsp;|
|```__lt__(self, other)```              |<br>```self < other```のふるまいを定義<br>&thinsp;|
|```__gt__(self, other)```              |<br>```self > other```のふるまいを定義<br>&thinsp;|
|```__le__(self, other)```              |<br>```self <= other```のふるまいを定義<br>&thinsp;|
|```__ge__(self, other)```              |<br>```self >= other```のふるまいを定義<br>&thinsp;|
|```__lshift__(self, other)```          |<br>```self << other```のふるまいを定義<br>&thinsp;|
|```__lshift__(self, other)```          |<br>```self >> other```のふるまいを定義<br>&thinsp;|
|```__and__(self, other)```             |<br>```self and other```のふるまいを定義<br>&thinsp;|
|```__or__(self, other)```              |<br>```self or other```のふるまいを定義<br>&thinsp;|
|```__xor__(self, other)```             |<br>```self ^ other```のふるまいを定義<br>&thinsp;|
|```__not__(self)```                    |<br>```not self```のふるまいを定義<br>&thinsp;|
|```__abs__(self)```                    |<br>```abs(self)```のふるまいを定義<br>&thinsp;|
|```__len__(self)```                    |<br>```len(self)```のふるまいを定義<br>&thinsp;|
|```__int__(self)```                    |<br>```int(self)```のふるまいを定義<br>&thinsp;|
|```__str__(self)```                    |<br>```str(self)```のふるまいを定義<br>&thinsp;|
|```__float__(self)```                  |<br>```float(self)```のふるまいを定義<br>&thinsp;|
|```__list__(self)```                   |<br>```list(self)```のふるまいを定義<br>&thinsp;|
|```__getitem__(self, other)```         |<br>要素の参照(```self[other]```)のふるまいを定義<br>&thinsp;|
|```__setitem__(self, other1, other2)```|<br>要素の置換(```self[other1] = other2```)のふるまいを定義<br>&thinsp;|
|```__delitem__(self, other)```         |<br>要素の削除(```del self[other1]```)のふるまいを定義<br>&thinsp;|
|```__hash__(self)```                   |<br>```hash(self)```のふるまいを定義<br>辞書型などで使用するときには必須<br>&thinsp;|
|```__contains__(self, other)```        |<br>```other in self```のふるまいを定義<br>&thinsp;|
|```__iter__(self)```                   |<br>```for ~~~ in self:```の最初の処理を定義<br>&thinsp;|
|```__next__(self)```                   |<br>```for value in self:```が繰り返すごとに行われる処理<br>```raise StopIteration```を実行することでループを抜ける<br>値を返すと```value```に代入される<br>&thinsp;|
|```__del__(self)```                    |<br>```del self```のふるまいを定義<br>&thinsp;|
|```__call__(self, other1, ...)```      |<br>```self(other1, ...)```のふるまいを定義<br>関数として利用するときの定義<br>&thinsp;|
|```__format__(self)```                 |<br>```"{}...".format(self)```のふるまいを定義<br>&thinsp;|

もし```self += other```の※ふるまいを変えるときは
```__add__(self, other)```のaddの前に"```i```"を付けた```__iadd__(self, other)```を追加して定義できます。

```self *= other```も※同じように
```__mul__(self, other)```のmulの前に"```i```"を付けた```__imul__(self, other)```を追加して定義できます。

※```__add__(self, other)```が定義されていたら基本的には```self += other```は```self = self + other```と勝手に定義される。
※```__mul__(self, other)```も同じように定義されていたら基本的には```self *= other```は```self = self * other```と勝手に定義される。

## ↓重要↓
もし```other + self```(```self```は自作データ型)を有効にするときは
```__add__(self, other)```のaddの前に"```r```"を付けた```__radd__(self, other)```を```class データ型```に追加して定義できます。

```other - self```(```self```は自作データ型)も同じように
```__sub__(self, other)```のsubの前に"```r```"を付けた```__rsub__(self, other)```を```class データ型```に追加して定義できます。

* * *
```hmath.×××(self)```などライブラリの関数のふるまいを変えたいときは```__×××__(self)```が使えます。

是非今回のことを活用してください。