今回はpythonの
様々な特殊メソッドの
挙動をコードを実装して
一つずつ確認します
[PR]※本サイトには、プロモーションが含まれています
合わせて読みたい | 記事の内容 |
【python入門】pythonのclassを解説:オブジェクト指向プログラミングへの第一歩 | クラスとインスタンスを説明 |
【python入門】class構文 : データ属性とメソッドについて理解する | データ属性とメソッドを説明 |
目次
特殊メソッドとは ?
ある特定の操作をクラスオブジェクトに対して行った時
呼び出されるタイミングが決まっているメソッド
特殊メソッドでは関数が実行されたときの
操作や演算子の挙動を定義することが出来ます
特殊メソッド文法
メソッド名の前後にアンダースコア(__)を2個つけたもの
__init__
特殊メソッドを紹介します
__init__
インスタンスが生成された後
作成されたインスタンスを初期化するために
呼び出されます
class User_info:
def __init__(self, name, age, address, score):
self.name = name
self.age = age
self.address = address
self.score = score
user = User_info("武", 18, " Takeshi@gmail.com ", 600)
print(f"Name : {user.name}, Age : {user.age}, Address : {user.address}, Score : {user.score}")
実行結果
Name : 武, Age : 18, Address : Takeshi@gmail.com , Score : 600
上記コードはインスタンスが生成された直後に
実行されます
インスタンスが初期化され
新たなインスタンス変数が定義されていることが確認できます
関数による挙動
特殊メソッドは関数が実行された時の挙動を定義できます
__repr__
インスタンスを文字列型に変換できます
下記コードの動作を確認後
__repr__を加えて挙動を確認します
class User_info:
def __init__(self, name, age, address, score):
self.name = name
self.age = age
self.address = address
self.score = score
user = User_info("武", 18, " Takeshi@gmail.com ", 600)
print(user)
実行結果
<__main__.User_info object at 0x00000141D74B5090>
オブジェクトの名前とアドレスが出力されました
__repr__でオブジェクトのprint出力を書き換えます
class User_info:
def __init__(self, name, age, address, score):
self.name = name
self.age = age
self.address = address
self.score = score
def __repr__(self) :
return f"<User id:{id(self)} name :{self.name}>"
user = User_info("武", 18, " Takeshi@gmail.com ", 600)
print(user)
実行結果
<User id:1905769468368 name :武>
インスタンスの情報が
簡単に確認できるように
なりました。
__len__
len関数の引数にオブジェクトを
加えたときの動作を確認します
class User_info:
def __init__(self, name, age, address, score):
self.name = name
self.age = age
self.address = address
self.score = score
def __len__(self):
return len(self.name)
user = User_info("武", 18, " Takeshi@gmail.com ", 600)
print(len(user))
実行結果
1
len関数を実行した時
名前の長さを取得する
ように定義してます
__str__
str関数やprint関数が呼び出されたとき
そのオブジェクトの「非公式の (informal)」文字列表現を返します
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"MyClass instance - Name: {self.name}, Age: {self.age}"
# インスタンスを作成
obj = MyClass("Alice", 30)
# print()やstr()で__str__()の戻り値が使われる
print(obj) # 出力: MyClass instance - Name: Alice, Age: 30
print(str(obj)) # 出力: MyClass instance - Name: Alice, Age: 30
実行結果
MyClass instance - Name: Alice, Age: 30
MyClass instance - Name: Alice, Age: 30
文字列を定義して
返していること
が確認できます
__bytes__
オブジェクトをバイト列に変換するための特殊メソッド
組み込み関数bytesがオブジェクトに対して
呼び出された時に実行されます
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
def __bytes__(self):
# 名前と年齢をバイト列に変換して結合
name_bytes = self.name.encode('utf-8')
age_bytes = str(self.age).encode('utf-8')
return name_bytes + b' ' + age_bytes
# インスタンスを作成
obj = MyClass("Alice", 30)
# bytes()で__bytes__()の戻り値が使われる
print(bytes(obj)) # 出力: b'Alice 30'
実行結果
b'Alice 30'
バイトに変換して
名前と年齢を結合して
返しているのが確認
できます
__format__
オブジェクトが指定されたフォーマット仕様に従って
フォーマットされる方法をカスタマイズするために使用されます
class MyClass:
def __init__(self, value):
self.value = value
def __format__(self, format_spec):
if format_spec == 'hex':
return hex(self.value)
elif format_spec == 'bin':
return bin(self.value)
else:
return str(self.value)
# インスタンスを作成
obj = MyClass(42)
# format()関数とフォーマット指定子を使用
print(format(obj, 'hex'))
print(format(obj, 'bin'))
print(format(obj, ''))
実行結果
0x2a
0b101010
42
フォーマット関数の
処理を指定子毎に
変えているのが
確認できますね
__hash__
ブジェクトのハッシュ値を返すための特殊メソッド
同じ内容を持つオブジェクトは同じハッシュ値ということが
以下コードで確認できます
class MyClass:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, MyClass):
return self.value == other.value
return False
def __hash__(self):
return hash(self.value)
# インスタンスを作成
obj1 = MyClass(42)
obj2 = MyClass(42)
obj3 = MyClass(43)
# ハッシュ値を確認
print(hash(obj1)) # 出力: ハッシュ値 (例: 42 のハッシュ値)
print(hash(obj2)) # 出力: 同じハッシュ値 (例: 42 のハッシュ値)
print(hash(obj3)) # 出力: 異なるハッシュ値 (例: 43 のハッシュ値)
# 等価性の確認
print(obj1 == obj2) # 出力: True
print(obj1 == obj3) # 出力: False
実行結果
42
42
43
True
False
__int__
オブジェクトを整数型に変換するための特殊メソッド
組み込み関数 int()がオブジェクトに対して
呼び出された時に使用します
class MyClass:
def __init__(self, value):
self.value = value
def __int__(self):
return int(self.value)
# インスタンスを作成
obj = MyClass(42.7)
# int() 関数で __int__() の戻り値が使われる
print(int(obj)) # 出力: 42
実行結果
42
整数型に変換されてます!
__float__
オブジェクトを浮動小数点数型に変換するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __float__(self):
return float(self.value)
# インスタンスを作成
obj = MyClass(42)
# float() 関数で __float__() の戻り値が使われる
print(float(obj)) # 出力: 42.0
実行結果
42.0
少数型に変換されてます
演算子による挙動
演算子の挙動も特殊メソッドで定義することができます
__add__
オブジェクトの加算操作 (+
) を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __add__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value + other.value)
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(20)
# + 演算子を使用した加算
result = obj1 + obj2
print(result) # 出力: MyClass(30)
実行結果
30
__sub__
オブジェクトの減算操作 (-
) を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __sub__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value - other.value)
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(3)
# - 演算子を使用した減算
result = obj1 - obj2
print(result) # 出力: MyClass(7)
実行結果
7
__mul__
オブジェクトの乗算操作 (*
) を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __mul__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value * other.value)
elif isinstance(other, (int, float)):
return MyClass(self.value * other)
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(3)
# * 演算子を使用した乗算
result = obj1 * obj2
print(result) # 出力: MyClass(30)
実行結果
30
__truediv__
オブジェクトの除算操作 (/
) を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __truediv__(self, other):
if isinstance(other, MyClass):
if other.value != 0:
return MyClass(self.value / other.value)
raise ZeroDivisionError("division by zero in MyClass")
elif isinstance(other, (int, float)):
if other != 0:
return MyClass(self.value / other)
raise ZeroDivisionError("division by zero in MyClass")
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(2)
# / 演算子を使用した除算
result = obj1 / obj2
print(result) # 出力: MyClass(5.0)
実行結果
5.0
__and__
オブジェクトの論理積(ビットごとの AND)操作を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __and__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value & other.value)
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(12) # 12は1100
obj2 = MyClass(10) # 10は1010
# & 演算子を使用したビットごとの AND 演算
result = obj1 & obj2
print(result) # 出力: MyClass(8) # 8は1000
実行結果
MyClass(8)
ANDの
真理値表を確認すると
オブジェクト同士で
論理積を行っていることが
確認できます
A | B | result |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
__or__
オブジェクトの論理和(ビットごとの OR)操作 (|
) を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __or__(self, other):
if isinstance(other, MyClass):
return MyClass(self.value | other.value)
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(12) # 12は1100
obj2 = MyClass(10) # 10は1010
# | 演算子を使用したビットごとの OR 演算
result = obj1 | obj2
print(result) # 出力: MyClass(14) # 14は1110
実行結果
MyClass(14)
ANDの
真理値表を確認すると
オブジェクト同士で
論理和を行っていることが
確認できます
A | B | result |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
__lt__
オブジェクトの大小比較(<)に使用されます
class MyClass:
def __init__(self, value):
self.value = value
def __lt__(self, other):
if isinstance(other, MyClass):
return self.value < other.value
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(20)
# < 演算子を使用した比較
print(obj1 < obj2) # 出力: True
print(obj2 < obj1) # 出力: False
実行結果
True
False
__gt__
オブジェクトの大小比較(>)に使用されます
class MyClass:
def __init__(self, value):
self.value = value
def __gt__(self, other):
if isinstance(other, MyClass):
return self.value > other.value
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(15)
obj3 = MyClass(5)
# > 演算子を使用した比較
print(obj1 > obj2) # 出力: False
print(obj1 > obj3) # 出力: True
実行結果
False
True
__le__
オブジェクトの「以下」 (<=
) 演算を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __le__(self, other):
if isinstance(other, MyClass):
return self.value <= other.value
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(15)
obj3 = MyClass(5)
# <= 演算子を使用した比較
print(obj1 <= obj2) # 出力: True
print(obj1 <= obj3) # 出力: False
実行結果
True
False
__ge__
オブジェクトの「以上」 (>=
) 演算を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __ge__(self, other):
if isinstance(other, MyClass):
return self.value >= other.value
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(15)
obj3 = MyClass(5)
# >= 演算子を使用した比較
print(obj1 >= obj2) # 出力: False
print(obj1 >= obj3) # 出力: True
実行結果
False
True
__eq__
オブジェクトの等価性(==)を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, MyClass):
return self.value == other.value
return NotImplemented
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(10)
obj3 = MyClass(20)
# == 演算子を使用した比較
print(obj1 == obj2) # 出力: True
print(obj1 == obj3) # 出力: False
実行結果
True
False
__ne__
ブジェクトの不等価性(!=)を定義するための特殊メソッド
class MyClass:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, MyClass):
return self.value == other.value
return NotImplemented
def __ne__(self, other):
return not self.__eq__(other)
def __repr__(self):
return f"MyClass({self.value})"
# インスタンスを作成
obj1 = MyClass(10)
obj2 = MyClass(10)
obj3 = MyClass(20)
# != 演算子を使用した比較
print(obj1 != obj2) # 出力: False
print(obj1 != obj3) # 出力: True
実行結果
False
True