Python | 特殊メソッドの使い方

公開日:2021/6/3

Pythonでクラスを用いる際,特殊メソッド(special methods)を利用することができる.主要な特殊メソッド(__str__, __eq__, __hash__, __bool__, __len__)を挙げ,以下に使い方を記す.

◆実施環境

Python 3.8.8

  1. 特殊メソッド

■__str__(オブジェクトを文字列に変換)

# 1の処理
class Chocolate:
  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  def __str__(self):
    return self.maker + ',' + self.brand + ',' + str(self.year)

Choco1 = Chocolate('Meiji','Fran',1999)
print(Choco1)
Choco1_str = str(Choco1)
print(Choco1_str)

■実行結果

# 1の結果
Meiji,Fran,1999
Meiji,Fran,1999

■__eq__(“=="利用時に呼び出される.等しいかどうか出力)

# 1の処理
class Chocolate:

  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  def __eq__(self,other): # brandとyearが同じだと,Choco1とChoco2は同じとみなす
    return(self.brand == other.brand) and (self.year == other.year)

Choco1 = Chocolate('Meiji','Fran',1999)
Choco2 = Chocolate('aaa','Fran',1999) # MakerがChoco1と異なる
print(Choco1 == Choco2)

# 2の処理
class Chocolate:

  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  def __eq__(self,other): # brandとyearが同じだと,Choco1とChoco2は同じとみなす
    return(self.brand == other.brand) and (self.year == other.year)

Choco1 = Chocolate('Meiji','Fran',1999)
Choco2 = Chocolate('Meiji','Fran',2005) # yearがChoco1と異なる
print(Choco1 == Choco2)

■実行結果

# 1の結果
True

# 2の結果
False

■__hash__(オブジェクトをhash値にして返す)

# 1の処理
class Chocolate:
  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  '''
  "hash"は辞書型やセット型でキーを入れたり,
  "=="を用いて等しいか確認するのに有用
  '''
  def __hash__(self):
    return hash(self.maker + self.brand) # makerとbrandを足し合わせた値がhash値になる

Choco1 = Chocolate('Meiji','Fran',1999) # Choco1とChoco3は同じhash値になる
Choco2 = Chocolate('Meiji','aaa',2005)
Choco3 = Chocolate('Meiji','Fran',2005)

print(hash(Choco1))
print(hash(Choco2))
print(hash(Choco3))

■実行結果

# 1の結果
6608503502684652
-1110770206646494095
6608503502684652

■__bool__(オブジェクトをTrue/Falseで返す)

# 1の処理
class Chocolate:
  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  def __bool__(self):
    return True if self.year >= 2000 else False

Choco1 = Chocolate('Meiji','Fran',1999)
Choco2 = Chocolate('Meiji','aaa',2005)
Choco3 = Chocolate('Meiji','Fran',2005)

# 出力方法1(True or False)
print(bool(Choco1))
print(bool(Choco2))
print(bool(Choco3))

# 出力方法2(Formatを用いるT/F)
print(f'Choco1の発売年は2000年以降であるか?{bool(Choco1)}')
print(f'Choco2の発売年は2000年以降であるか?{bool(Choco2)}')
print(f'Choco3の発売年は2000年以降であるか?{bool(Choco3)}')

# 出力方法3(if文を用いるT/F)
if Choco1:
  print('Choco1の発売年は2000年以降である')
else:
  print('Choco1の発売年は1999年以前である')

if Choco2:
  print('Choco2の発売年は2000年以降である')
else:
  print('Choco2の発売年は1999年以前である')

if Choco3:
  print('Choco3の発売年は2000年以降である')
else:
  print('Choco3の発売年は1999年以前である')

■実行結果

# 1の結果
False # 出力方法1の結果
True
True

Choco1の発売年は2000年以降であるか?False # 出力方法2の結果
Choco2の発売年は2000年以降であるか?True
Choco3の発売年は2000年以降であるか?True

Choco1の発売年は1999年以前である # 出力方法3の結果
Choco2の発売年は2000年以降である
Choco3の発売年は2000年以降である

■__len__(オブジェクトの長さを返す)

# 1の処理
class Chocolate:
  def __init__(self,maker,brand,year):
    self.maker = maker
    self.brand = brand
    self.year = year

  def __len__(self):
    return len(self.brand)

Choco1 = Chocolate('Meiji','Fran',1999)
Choco2 = Chocolate('Meiji','aaa',2005)
Choco3 = Chocolate('Meiji','Fran',2005)

print(len(Choco1)) # brandの長さを出力
print(len(Choco2))
print(len(Choco3))

■実行結果

# 1の結果
4
3
4

以上