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 ではダックタイピングがより柔軟になりました。