Pythonの特殊メソッド一覧を備忘録としてまとめてみた。

## 特殊メソッド利用
* オブジェクトの振る舞いの変更、特殊な挙動を持たせたい場合に特殊メソッドを使用する
* インスタンスに対して演算子を使った操作ができる
* 演算子使用時に特殊メソッドが呼び出される

## 算術演算子を定義する特殊メソッド
* `__add__(self,オブジェクト)`:「＋」で足し算を行うときに呼び出されるメソッド(+演算子使用時に呼び出される）
* `__sub__(self,オブジェクト)`:「―」で引き算を行うときに呼び出されるメソッド
* `__mul__(self,オブジェクト)`:「＊」で掛け算を行うときに呼び出されるメソッド
* `__truediv__(self,オブジェクト)`:「／」で割り算を行うときに呼び出されるメソッド
* `__floordiv__(self,オブジェクト)`:「／／」で割り算を行うときに呼び出されるメソッド(小数点以下切り捨てで整数値で返す）

なお、`__iadd__()`,`__isub__()`のように上記のメソッド名の頭にiを加えると複合演算子「+=」、「-=」、を定義できる。他も同様。

```python
class Car():
    def __init__(self,value):
        self.value = value
    
    def __add__(self,other):
        return self.value + other.value
    
    def __sub__(self,other):
        return self.value - other.value
    
    def __mul__(self,other):
        return self.value * other.value
    
    def __truediv__(self,other):
        return self.value / other.value
    
    def __floordiv__(self,other):
        return self.value // other.value

car1 = Car(10)
car2 = Car(20)
print(car1+car2) #30
print(car1-car2) #-10
print(car1*car2) #200
print(car1/car2) #0.5
print(car1//car2) #0
```


## ビット演算子を定義する特殊メソッド
* `__and__(self,オブジェクト)`:「&」を使うときに呼び出されるメソッド
* `__or__(self,オブジェクト)`:「|」を使うときに呼び出されるメソッド

```python

class Car():
    def __init__(self,value):
        self.value = value
    
    def __and__(self,other):
        return self.value & other.value
    
    def __or__(self,other):
        return self.value | other.value

car1 = Car(1)
car2 = Car(0) 
print(car1&car2) #0
print(car1|car2) #1
```

## 比較演算子を定義する特殊メソッド[拡張比較 (rich comparison) メソッド]
* `__eq__(self,オブジェクト)`:「==」を使うときに呼び出されるメソッド
* `__ne__(self,オブジェクト)`:「!=」を使うときに呼び出されるメソッド
* `__lt__(self,オブジェクト)`:「<」を使うときに呼び出されるメソッド(less thanの意）
* `__gt__(self,オブジェクト)`:「>」を使うときに呼び出されるメソッド(greater thanの意）

```python
class Car():
    def __init__(self,value):
        self.value = value
    
    def __eq__(self,other):
        return self.value == other.value
    
    def __ne__(self,other):
        return self.value != other.value
    
    def __lt__(self,other):
        return self.value < other.value
    
    def __gt__(self,other):
        return self.value > other.value

car1 = Car(1)
car2 = Car(0)
print(car1==car2)
print(car1!=car2)
print(car1<car2)
print(car1>car2)
#以下、結果
False
True
False
True

```



## 型変換を定義する特殊メソッド
* `__int__(self)`:int()関数を使うときに呼び出されるメソッド
* `__float__(self)`:float()関数を使うときに呼び出されるメソッド
* `__str__(self)`:str()関数,組み込み関数 format(), print() を使うときに呼び出されるメソッド
* `__repr__(self)`:オブジェクトの文字列表記(オブジェクトの印字可能な表現を含む文字列）を返すメソッド


***※`__str__(self)`と`__repr__(self)`の違いについては下記記載***

なお参考までに：[http://taustation.com/python3-str-repr/],  [https://gammasoft.jp/blog/use-diffence-str-and-repr-python/]

* `__bytes__(self)`:bytes()関数を使うときに呼び出されるメソッド
* `__format__(self,form_spec)`:format()メソッド使用時に呼び出される[https://docs.python.org/ja/3/library/functions.html#format]


```python
class Car():
    def __init__(self,value):
        self.value = value
        self.str = "あいうえお"
    
    def __int__(self):
        return int(self.value)
    
    def __float__(self):
        return float(self.value)
    
#    def __str__(self):
#        return str(self.value)
    
    def __repr__(self):
        return repr(self.value)
    
    def __bytes__(self):
        return bytes(self.value)
    
    def __format__(self, form_spec):
        return self.str

car1 = Car(1)
car_str = Car("a")
print(int(car1))
print(float(car1))

print(str(car1))
print(car_str)
print('{}'.format(car1,0))
repr(car1)

#以下、結果
1
1.0
1
'a'
あいうえお
```

### ※__str__()メソッドと __repr__()について
```python

#__str__()メソッドと __repr__()を定義しなかったとき
print(str(car1))     #<__main__.Car object at 0x000002A4A2B16F60>
print(car1)          #<__main__.Car object at 0x000002A4A2B16F60>
print(car_str)       #<__main__.Car object at 0x000002A4A2B16940>

#__str__()だけを定義したとき
car1 = Car(1)
car_str = Car("a")
print(str(car1))  #1
print(car1)       #1
print(car_str)    #a

#__repr__()だけを定義したとき
car1 = Car(1)
car_str = Car("a")
print(str(car1)) #1
print(car1)      #1
print(car_str)   #'a'

# 両方定義したとき
import datetime
today = datetime.date.today()
print(str(today))    #2019-08-19
print(repr(today))   #datetime.date(2019, 8, 19)
```

## コンテナ型で利用する特殊メソッド
* コンテナ型とはリストやタプル、ディクショナリのように、複数の要素数を持つ型の総称
* `__len__(self)`:組み込み関数len()を呼び出したときに実行されるメソッド
* `__getitem__(self,キー)` :要素を参照(`list[1]`,`d["key"]`)するときに呼び出されるメソッド
* `__setitem__(self,キー)`:引数のキーに要素を代入メソッド
* `__delitem__(self,キー)`:del文が使用されたときに呼び出されるメソッド
* `__iter__(self)`:iter()関数使用時に呼び出される
* `__conteins__(self)`:比較演算子「in」が使われたときに呼び出されるメソッド（戻り値はTrueかFalse）

## アトリビュートのアクセスに利用される特殊メソッド
* `__getattr__(self,アトリビュート名)`:未定義のアトリビュートが参照されるときに呼び出されるメソッド
* `__getattribute__(self,キー)` :全てのアトリビュートが参照されるときに呼び出されるメソッド
* `__setattr__(self,キー)`:オブジェクトのアトリビュートに代入しようとするときに呼び出されるメソッド（このメソッド内で代入を行わないとアトリビュートに追加ができない


## 参考文献
* みんなのPython 第4版
* エキスパートPythonプログラミング改訂2版