Python のメソッドとバウンドメソッドの仕組み
Python の「メソッド」は、関数がインスタンスに束縛されたものです。関数とバウンドメソッドの違いを理解すると、Python のオブジェクトモデルが明確になります。
関数とメソッドの違い
class Calculator:
def add(self, a, b):
return a + b
calc = Calculator()
# クラスから取得:関数
func = Calculator.add
print(type(func)) # <class 'function'>
# インスタンスから取得:バウンドメソッド
method = calc.add
print(type(method)) # <class 'method'>
バウンドメソッドの構造
バウンドメソッドは、関数と束縛されたインスタンスへの参照を保持しています。
print(method.__func__) # <function Calculator.add>
print(method.__self__) # <Calculator object>
バウンドメソッドを呼び出すと、__self__ が自動的に第一引数として渡されます。
# 以下は同じ結果
print(calc.add(1, 2)) # 3
print(Calculator.add(calc, 1, 2)) # 3
print(method(1, 2)) # 3
動的なメソッドバインディング
関数を後からインスタンスにバインドすることもできます。
import types
def greet(self):
return f"Hello, {self.name}!"
class Person:
def __init__(self, name):
self.name = name
p = Person("Alice")
p.greet = types.MethodType(greet, p)
print(p.greet()) # Hello, Alice!
アンバウンドメソッド(Python 2 との違い)
Python 2 ではクラスから取得したメソッドは「アンバウンドメソッド」でしたが、Python 3 では単なる関数として扱われます。
Python 2
クラス.メソッド → アンバウンドメソッド(self の型チェックあり)
Python 3
クラス.メソッド → 単なる関数(型チェックなし)
この変更により、Python 3 ではダックタイピングがより柔軟になりました。