【python入門】特殊メソッドの挙動を確認する

python
Yamu
Yamu

今回は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 :武>
Yamu
Yamu

インスタンスの情報が
簡単に確認できるように
なりました。

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

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
Yamu
Yamu

文字列を定義して
返していること

が確認できます

__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'
Yamu
Yamu

バイトに変換して
名前と年齢を結合して
返しているのが確認
できます

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

フォーマット関数の
処理を指定子毎に

変えているのが
確認できますね

__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
Yamu<br>
Yamu

整数型に変換されてます!

__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
Yamu<br>
Yamu

少数型に変換されてます

演算子による挙動

演算子の挙動も特殊メソッドで定義することができます

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

ANDの
真理値表を確認すると
オブジェクト同士で

論理積を行っていることが
確認できます

ABresult
111
100
010
000
AND(論理積)

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

ANDの
真理値表を確認すると
オブジェクト同士で

論理和を行っていることが
確認できます

ABresult
000
011
101
111
or(論理和)

__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
タイトルとURLをコピーしました